blob: be1370747c5401ebd9bd5b1a1bba60d7e38c7709 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
Michael Wright3dd60e22019-03-27 22:06:44 +000020#define LOG_NDEBUG 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
31// Log debug messages about registrations.
32#define DEBUG_REGISTRATION 0
33
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
38#define DEBUG_FOCUS 0
39
40// Log debug messages about the app switch latency optimization.
41#define DEBUG_APP_SWITCH 0
42
43// Log debug messages about hover events.
44#define DEBUG_HOVER 0
45
46#include "InputDispatcher.h"
47
Michael Wrightd02c5b62014-02-10 15:10:22 -080048#include <errno.h>
Siarhei Vishniakou443ad902019-03-06 17:25:41 -080049#include <inttypes.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080050#include <limits.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080051#include <sstream>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070052#include <stddef.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080053#include <time.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070054#include <unistd.h>
55
Michael Wright2b3c3302018-03-02 17:19:13 +000056#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080057#include <android-base/stringprintf.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070058#include <log/log.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070059#include <utils/Trace.h>
60#include <powermanager/PowerManager.h>
Robert Carr4e670e52018-08-15 13:26:12 -070061#include <binder/Binder.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080062
63#define INDENT " "
64#define INDENT2 " "
65#define INDENT3 " "
66#define INDENT4 " "
67
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080068using android::base::StringPrintf;
69
Michael Wrightd02c5b62014-02-10 15:10:22 -080070namespace android {
71
72// Default input dispatching timeout if there is no focused application or paused window
73// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000074constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080075
76// Amount of time to allow for all pending events to be processed when an app switch
77// key is on the way. This is used to preempt input dispatch and drop input events
78// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000079constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080080
81// Amount of time to allow for an event to be dispatched (measured since its eventTime)
82// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000083constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080084
85// Amount of time to allow touch events to be streamed out to a connection before requiring
86// that the first event be finished. This value extends the ANR timeout by the specified
87// amount. For example, if streaming is allowed to get ahead by one second relative to the
88// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000089constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080090
91// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +000092constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
93
94// Log a warning when an interception call takes longer than this to process.
95constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -080096
97// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +000098constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
99
Prabir Pradhan42611e02018-11-27 14:04:02 -0800100// Sequence number for synthesized or injected events.
101constexpr uint32_t SYNTHESIZED_EVENT_SEQUENCE_NUM = 0;
102
Michael Wrightd02c5b62014-02-10 15:10:22 -0800103
104static inline nsecs_t now() {
105 return systemTime(SYSTEM_TIME_MONOTONIC);
106}
107
108static inline const char* toString(bool value) {
109 return value ? "true" : "false";
110}
111
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800112static std::string motionActionToString(int32_t action) {
113 // Convert MotionEvent action to string
114 switch(action & AMOTION_EVENT_ACTION_MASK) {
115 case AMOTION_EVENT_ACTION_DOWN:
116 return "DOWN";
117 case AMOTION_EVENT_ACTION_MOVE:
118 return "MOVE";
119 case AMOTION_EVENT_ACTION_UP:
120 return "UP";
121 case AMOTION_EVENT_ACTION_POINTER_DOWN:
122 return "POINTER_DOWN";
123 case AMOTION_EVENT_ACTION_POINTER_UP:
124 return "POINTER_UP";
125 }
126 return StringPrintf("%" PRId32, action);
127}
128
129static std::string keyActionToString(int32_t action) {
130 // Convert KeyEvent action to string
Michael Wright3dd60e22019-03-27 22:06:44 +0000131 switch (action) {
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800132 case AKEY_EVENT_ACTION_DOWN:
133 return "DOWN";
134 case AKEY_EVENT_ACTION_UP:
135 return "UP";
136 case AKEY_EVENT_ACTION_MULTIPLE:
137 return "MULTIPLE";
138 }
139 return StringPrintf("%" PRId32, action);
140}
141
Michael Wright3dd60e22019-03-27 22:06:44 +0000142static std::string dispatchModeToString(int32_t dispatchMode) {
143 switch (dispatchMode) {
144 case InputTarget::FLAG_DISPATCH_AS_IS:
145 return "DISPATCH_AS_IS";
146 case InputTarget::FLAG_DISPATCH_AS_OUTSIDE:
147 return "DISPATCH_AS_OUTSIDE";
148 case InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER:
149 return "DISPATCH_AS_HOVER_ENTER";
150 case InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT:
151 return "DISPATCH_AS_HOVER_EXIT";
152 case InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT:
153 return "DISPATCH_AS_SLIPPERY_EXIT";
154 case InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER:
155 return "DISPATCH_AS_SLIPPERY_ENTER";
156 }
157 return StringPrintf("%" PRId32, dispatchMode);
158}
159
Michael Wrightd02c5b62014-02-10 15:10:22 -0800160static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
161 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
162 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
163}
164
165static bool isValidKeyAction(int32_t action) {
166 switch (action) {
167 case AKEY_EVENT_ACTION_DOWN:
168 case AKEY_EVENT_ACTION_UP:
169 return true;
170 default:
171 return false;
172 }
173}
174
175static bool validateKeyEvent(int32_t action) {
176 if (! isValidKeyAction(action)) {
177 ALOGE("Key event has invalid action code 0x%x", action);
178 return false;
179 }
180 return true;
181}
182
Michael Wright7b159c92015-05-14 14:48:03 +0100183static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800184 switch (action & AMOTION_EVENT_ACTION_MASK) {
185 case AMOTION_EVENT_ACTION_DOWN:
186 case AMOTION_EVENT_ACTION_UP:
187 case AMOTION_EVENT_ACTION_CANCEL:
188 case AMOTION_EVENT_ACTION_MOVE:
189 case AMOTION_EVENT_ACTION_OUTSIDE:
190 case AMOTION_EVENT_ACTION_HOVER_ENTER:
191 case AMOTION_EVENT_ACTION_HOVER_MOVE:
192 case AMOTION_EVENT_ACTION_HOVER_EXIT:
193 case AMOTION_EVENT_ACTION_SCROLL:
194 return true;
195 case AMOTION_EVENT_ACTION_POINTER_DOWN:
196 case AMOTION_EVENT_ACTION_POINTER_UP: {
197 int32_t index = getMotionEventActionPointerIndex(action);
Dan Albert1bd2fc02016-02-02 15:11:57 -0800198 return index >= 0 && index < pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800199 }
Michael Wright7b159c92015-05-14 14:48:03 +0100200 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
201 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
202 return actionButton != 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800203 default:
204 return false;
205 }
206}
207
Michael Wright7b159c92015-05-14 14:48:03 +0100208static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800209 const PointerProperties* pointerProperties) {
Michael Wright7b159c92015-05-14 14:48:03 +0100210 if (! isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211 ALOGE("Motion event has invalid action code 0x%x", action);
212 return false;
213 }
214 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000215 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Michael Wrightd02c5b62014-02-10 15:10:22 -0800216 pointerCount, MAX_POINTERS);
217 return false;
218 }
219 BitSet32 pointerIdBits;
220 for (size_t i = 0; i < pointerCount; i++) {
221 int32_t id = pointerProperties[i].id;
222 if (id < 0 || id > MAX_POINTER_ID) {
223 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
224 id, MAX_POINTER_ID);
225 return false;
226 }
227 if (pointerIdBits.hasBit(id)) {
228 ALOGE("Motion event has duplicate pointer id %d", id);
229 return false;
230 }
231 pointerIdBits.markBit(id);
232 }
233 return true;
234}
235
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800236static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800237 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800238 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800239 return;
240 }
241
242 bool first = true;
243 Region::const_iterator cur = region.begin();
244 Region::const_iterator const tail = region.end();
245 while (cur != tail) {
246 if (first) {
247 first = false;
248 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800249 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800250 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800251 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800252 cur++;
253 }
254}
255
Tiger Huang721e26f2018-07-24 22:26:19 +0800256template<typename T, typename U>
257static T getValueByKey(std::unordered_map<U, T>& map, U key) {
258 typename std::unordered_map<U, T>::const_iterator it = map.find(key);
259 return it != map.end() ? it->second : T{};
260}
261
Michael Wrightd02c5b62014-02-10 15:10:22 -0800262
263// --- InputDispatcher ---
264
Garfield Tan00f511d2019-06-12 16:55:40 -0700265InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
266 : mPolicy(policy),
267 mPendingEvent(nullptr),
268 mLastDropReason(DROP_REASON_NOT_DROPPED),
269 mAppSwitchSawKeyDown(false),
270 mAppSwitchDueTime(LONG_LONG_MAX),
271 mNextUnblockedEvent(nullptr),
272 mDispatchEnabled(false),
273 mDispatchFrozen(false),
274 mInputFilterEnabled(false),
275 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
276 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800277 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800278 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800279
Yi Kong9b14ac62018-07-17 13:48:38 -0700280 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800281
282 policy->getDispatcherConfiguration(&mConfig);
283}
284
285InputDispatcher::~InputDispatcher() {
286 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800287 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800288
289 resetKeyRepeatLocked();
290 releasePendingEventLocked();
291 drainInboundQueueLocked();
292 }
293
294 while (mConnectionsByFd.size() != 0) {
295 unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
296 }
297}
298
299void InputDispatcher::dispatchOnce() {
300 nsecs_t nextWakeupTime = LONG_LONG_MAX;
301 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800302 std::scoped_lock _l(mLock);
303 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800304
305 // Run a dispatch loop if there are no pending commands.
306 // The dispatch loop might enqueue commands to run afterwards.
307 if (!haveCommandsLocked()) {
308 dispatchOnceInnerLocked(&nextWakeupTime);
309 }
310
311 // Run all pending commands if there are any.
312 // If any commands were run then force the next poll to wake up immediately.
313 if (runCommandsLockedInterruptible()) {
314 nextWakeupTime = LONG_LONG_MIN;
315 }
316 } // release lock
317
318 // Wait for callback or timeout or wake. (make sure we round up, not down)
319 nsecs_t currentTime = now();
320 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
321 mLooper->pollOnce(timeoutMillis);
322}
323
324void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
325 nsecs_t currentTime = now();
326
Jeff Browndc5992e2014-04-11 01:27:26 -0700327 // Reset the key repeat timer whenever normal dispatch is suspended while the
328 // device is in a non-interactive state. This is to ensure that we abort a key
329 // repeat if the device is just coming out of sleep.
330 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800331 resetKeyRepeatLocked();
332 }
333
334 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
335 if (mDispatchFrozen) {
336#if DEBUG_FOCUS
337 ALOGD("Dispatch frozen. Waiting some more.");
338#endif
339 return;
340 }
341
342 // Optimize latency of app switches.
343 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
344 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
345 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
346 if (mAppSwitchDueTime < *nextWakeupTime) {
347 *nextWakeupTime = mAppSwitchDueTime;
348 }
349
350 // Ready to start a new event.
351 // If we don't already have a pending event, go grab one.
352 if (! mPendingEvent) {
353 if (mInboundQueue.isEmpty()) {
354 if (isAppSwitchDue) {
355 // The inbound queue is empty so the app switch key we were waiting
356 // for will never arrive. Stop waiting for it.
357 resetPendingAppSwitchLocked(false);
358 isAppSwitchDue = false;
359 }
360
361 // Synthesize a key repeat if appropriate.
362 if (mKeyRepeatState.lastKeyEntry) {
363 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
364 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
365 } else {
366 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
367 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
368 }
369 }
370 }
371
372 // Nothing to do if there is no pending event.
373 if (!mPendingEvent) {
374 return;
375 }
376 } else {
377 // Inbound queue has at least one entry.
378 mPendingEvent = mInboundQueue.dequeueAtHead();
379 traceInboundQueueLengthLocked();
380 }
381
382 // Poke user activity for this event.
383 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
384 pokeUserActivityLocked(mPendingEvent);
385 }
386
387 // Get ready to dispatch the event.
388 resetANRTimeoutsLocked();
389 }
390
391 // Now we have an event to dispatch.
392 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700393 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800394 bool done = false;
395 DropReason dropReason = DROP_REASON_NOT_DROPPED;
396 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
397 dropReason = DROP_REASON_POLICY;
398 } else if (!mDispatchEnabled) {
399 dropReason = DROP_REASON_DISABLED;
400 }
401
402 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700403 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800404 }
405
406 switch (mPendingEvent->type) {
407 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
408 ConfigurationChangedEntry* typedEntry =
409 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
410 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
411 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
412 break;
413 }
414
415 case EventEntry::TYPE_DEVICE_RESET: {
416 DeviceResetEntry* typedEntry =
417 static_cast<DeviceResetEntry*>(mPendingEvent);
418 done = dispatchDeviceResetLocked(currentTime, typedEntry);
419 dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
420 break;
421 }
422
423 case EventEntry::TYPE_KEY: {
424 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
425 if (isAppSwitchDue) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800426 if (isAppSwitchKeyEvent(typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800427 resetPendingAppSwitchLocked(true);
428 isAppSwitchDue = false;
429 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
430 dropReason = DROP_REASON_APP_SWITCH;
431 }
432 }
433 if (dropReason == DROP_REASON_NOT_DROPPED
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800434 && isStaleEvent(currentTime, typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800435 dropReason = DROP_REASON_STALE;
436 }
437 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
438 dropReason = DROP_REASON_BLOCKED;
439 }
440 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
441 break;
442 }
443
444 case EventEntry::TYPE_MOTION: {
445 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
446 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
447 dropReason = DROP_REASON_APP_SWITCH;
448 }
449 if (dropReason == DROP_REASON_NOT_DROPPED
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800450 && isStaleEvent(currentTime, typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800451 dropReason = DROP_REASON_STALE;
452 }
453 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
454 dropReason = DROP_REASON_BLOCKED;
455 }
456 done = dispatchMotionLocked(currentTime, typedEntry,
457 &dropReason, nextWakeupTime);
458 break;
459 }
460
461 default:
462 ALOG_ASSERT(false);
463 break;
464 }
465
466 if (done) {
467 if (dropReason != DROP_REASON_NOT_DROPPED) {
468 dropInboundEventLocked(mPendingEvent, dropReason);
469 }
Michael Wright3a981722015-06-10 15:26:13 +0100470 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800471
472 releasePendingEventLocked();
473 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
474 }
475}
476
477bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
478 bool needWake = mInboundQueue.isEmpty();
479 mInboundQueue.enqueueAtTail(entry);
480 traceInboundQueueLengthLocked();
481
482 switch (entry->type) {
483 case EventEntry::TYPE_KEY: {
484 // Optimize app switch latency.
485 // If the application takes too long to catch up then we drop all events preceding
486 // the app switch key.
487 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800488 if (isAppSwitchKeyEvent(keyEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800489 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
490 mAppSwitchSawKeyDown = true;
491 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
492 if (mAppSwitchSawKeyDown) {
493#if DEBUG_APP_SWITCH
494 ALOGD("App switch is pending!");
495#endif
496 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
497 mAppSwitchSawKeyDown = false;
498 needWake = true;
499 }
500 }
501 }
502 break;
503 }
504
505 case EventEntry::TYPE_MOTION: {
506 // Optimize case where the current application is unresponsive and the user
507 // decides to touch a window in a different application.
508 // If the application takes too long to catch up then we drop all events preceding
509 // the touch into the other window.
510 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
511 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
512 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
513 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
Robert Carr740167f2018-10-11 19:03:41 -0700514 && mInputTargetWaitApplicationToken != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800515 int32_t displayId = motionEntry->displayId;
516 int32_t x = int32_t(motionEntry->pointerCoords[0].
517 getAxisValue(AMOTION_EVENT_AXIS_X));
518 int32_t y = int32_t(motionEntry->pointerCoords[0].
519 getAxisValue(AMOTION_EVENT_AXIS_Y));
520 sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
Yi Kong9b14ac62018-07-17 13:48:38 -0700521 if (touchedWindowHandle != nullptr
Robert Carr740167f2018-10-11 19:03:41 -0700522 && touchedWindowHandle->getApplicationToken()
523 != mInputTargetWaitApplicationToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800524 // User touched a different application than the one we are waiting on.
525 // Flag the event, and start pruning the input queue.
526 mNextUnblockedEvent = motionEntry;
527 needWake = true;
528 }
529 }
530 break;
531 }
532 }
533
534 return needWake;
535}
536
537void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
538 entry->refCount += 1;
539 mRecentQueue.enqueueAtTail(entry);
540 if (mRecentQueue.count() > RECENT_QUEUE_MAX_SIZE) {
541 mRecentQueue.dequeueAtHead()->release();
542 }
543}
544
545sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800546 int32_t x, int32_t y, bool addOutsideTargets, bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800547 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800548 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
549 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800550 const InputWindowInfo* windowInfo = windowHandle->getInfo();
551 if (windowInfo->displayId == displayId) {
552 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800553
554 if (windowInfo->visible) {
555 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
556 bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
557 | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
558 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800559 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
560 if (portalToDisplayId != ADISPLAY_ID_NONE
561 && portalToDisplayId != displayId) {
562 if (addPortalWindows) {
563 // For the monitoring channels of the display.
564 mTempTouchState.addPortalWindow(windowHandle);
565 }
566 return findTouchedWindowAtLocked(
567 portalToDisplayId, x, y, addOutsideTargets, addPortalWindows);
568 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800569 // Found window.
570 return windowHandle;
571 }
572 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800573
574 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
575 mTempTouchState.addOrUpdateWindow(
576 windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE, BitSet32(0));
577 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800578 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800579 }
580 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700581 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800582}
583
Michael Wright3dd60e22019-03-27 22:06:44 +0000584std::vector<InputDispatcher::TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
585 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
586 std::vector<TouchedMonitor> touchedMonitors;
587
588 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
589 addGestureMonitors(monitors, touchedMonitors);
590 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
591 const InputWindowInfo* windowInfo = portalWindow->getInfo();
592 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
593 addGestureMonitors(monitors, touchedMonitors,
594 -windowInfo->frameLeft, -windowInfo->frameTop);
595 }
596 return touchedMonitors;
597}
598
599void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
600 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset, float yOffset) {
601 if (monitors.empty()) {
602 return;
603 }
604 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
605 for (const Monitor& monitor : monitors) {
606 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
607 }
608}
609
Michael Wrightd02c5b62014-02-10 15:10:22 -0800610void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
611 const char* reason;
612 switch (dropReason) {
613 case DROP_REASON_POLICY:
614#if DEBUG_INBOUND_EVENT_DETAILS
615 ALOGD("Dropped event because policy consumed it.");
616#endif
617 reason = "inbound event was dropped because the policy consumed it";
618 break;
619 case DROP_REASON_DISABLED:
Michael Wright3a981722015-06-10 15:26:13 +0100620 if (mLastDropReason != DROP_REASON_DISABLED) {
621 ALOGI("Dropped event because input dispatch is disabled.");
622 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800623 reason = "inbound event was dropped because input dispatch is disabled";
624 break;
625 case DROP_REASON_APP_SWITCH:
626 ALOGI("Dropped event because of pending overdue app switch.");
627 reason = "inbound event was dropped because of pending overdue app switch";
628 break;
629 case DROP_REASON_BLOCKED:
630 ALOGI("Dropped event because the current application is not responding and the user "
631 "has started interacting with a different application.");
632 reason = "inbound event was dropped because the current application is not responding "
633 "and the user has started interacting with a different application";
634 break;
635 case DROP_REASON_STALE:
636 ALOGI("Dropped event because it is stale.");
637 reason = "inbound event was dropped because it is stale";
638 break;
639 default:
640 ALOG_ASSERT(false);
641 return;
642 }
643
644 switch (entry->type) {
645 case EventEntry::TYPE_KEY: {
646 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
647 synthesizeCancelationEventsForAllConnectionsLocked(options);
648 break;
649 }
650 case EventEntry::TYPE_MOTION: {
651 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
652 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
653 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
654 synthesizeCancelationEventsForAllConnectionsLocked(options);
655 } else {
656 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
657 synthesizeCancelationEventsForAllConnectionsLocked(options);
658 }
659 break;
660 }
661 }
662}
663
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800664static bool isAppSwitchKeyCode(int32_t keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800665 return keyCode == AKEYCODE_HOME
666 || keyCode == AKEYCODE_ENDCALL
667 || keyCode == AKEYCODE_APP_SWITCH;
668}
669
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800670bool InputDispatcher::isAppSwitchKeyEvent(KeyEntry* keyEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800671 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
672 && isAppSwitchKeyCode(keyEntry->keyCode)
673 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
674 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
675}
676
677bool InputDispatcher::isAppSwitchPendingLocked() {
678 return mAppSwitchDueTime != LONG_LONG_MAX;
679}
680
681void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
682 mAppSwitchDueTime = LONG_LONG_MAX;
683
684#if DEBUG_APP_SWITCH
685 if (handled) {
686 ALOGD("App switch has arrived.");
687 } else {
688 ALOGD("App switch was abandoned.");
689 }
690#endif
691}
692
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800693bool InputDispatcher::isStaleEvent(nsecs_t currentTime, EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800694 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
695}
696
697bool InputDispatcher::haveCommandsLocked() const {
698 return !mCommandQueue.isEmpty();
699}
700
701bool InputDispatcher::runCommandsLockedInterruptible() {
702 if (mCommandQueue.isEmpty()) {
703 return false;
704 }
705
706 do {
707 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
708
709 Command command = commandEntry->command;
710 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
711
712 commandEntry->connection.clear();
713 delete commandEntry;
714 } while (! mCommandQueue.isEmpty());
715 return true;
716}
717
718InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
719 CommandEntry* commandEntry = new CommandEntry(command);
720 mCommandQueue.enqueueAtTail(commandEntry);
721 return commandEntry;
722}
723
724void InputDispatcher::drainInboundQueueLocked() {
725 while (! mInboundQueue.isEmpty()) {
726 EventEntry* entry = mInboundQueue.dequeueAtHead();
727 releaseInboundEventLocked(entry);
728 }
729 traceInboundQueueLengthLocked();
730}
731
732void InputDispatcher::releasePendingEventLocked() {
733 if (mPendingEvent) {
734 resetANRTimeoutsLocked();
735 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700736 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800737 }
738}
739
740void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
741 InjectionState* injectionState = entry->injectionState;
742 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
743#if DEBUG_DISPATCH_CYCLE
744 ALOGD("Injected inbound event was dropped.");
745#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800746 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800747 }
748 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700749 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800750 }
751 addRecentEventLocked(entry);
752 entry->release();
753}
754
755void InputDispatcher::resetKeyRepeatLocked() {
756 if (mKeyRepeatState.lastKeyEntry) {
757 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700758 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800759 }
760}
761
762InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
763 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
764
765 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700766 uint32_t policyFlags = entry->policyFlags &
767 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800768 if (entry->refCount == 1) {
769 entry->recycle();
770 entry->eventTime = currentTime;
771 entry->policyFlags = policyFlags;
772 entry->repeatCount += 1;
773 } else {
Prabir Pradhan42611e02018-11-27 14:04:02 -0800774 KeyEntry* newEntry = new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100775 entry->deviceId, entry->source, entry->displayId, policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800776 entry->action, entry->flags, entry->keyCode, entry->scanCode,
777 entry->metaState, entry->repeatCount + 1, entry->downTime);
778
779 mKeyRepeatState.lastKeyEntry = newEntry;
780 entry->release();
781
782 entry = newEntry;
783 }
784 entry->syntheticRepeat = true;
785
786 // Increment reference count since we keep a reference to the event in
787 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
788 entry->refCount += 1;
789
790 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
791 return entry;
792}
793
794bool InputDispatcher::dispatchConfigurationChangedLocked(
795 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
796#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700797 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800798#endif
799
800 // Reset key repeating in case a keyboard device was added or removed or something.
801 resetKeyRepeatLocked();
802
803 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
804 CommandEntry* commandEntry = postCommandLocked(
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800805 & InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800806 commandEntry->eventTime = entry->eventTime;
807 return true;
808}
809
810bool InputDispatcher::dispatchDeviceResetLocked(
811 nsecs_t currentTime, DeviceResetEntry* entry) {
812#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700813 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
814 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800815#endif
816
817 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
818 "device was reset");
819 options.deviceId = entry->deviceId;
820 synthesizeCancelationEventsForAllConnectionsLocked(options);
821 return true;
822}
823
824bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
825 DropReason* dropReason, nsecs_t* nextWakeupTime) {
826 // Preprocessing.
827 if (! entry->dispatchInProgress) {
828 if (entry->repeatCount == 0
829 && entry->action == AKEY_EVENT_ACTION_DOWN
830 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
831 && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
832 if (mKeyRepeatState.lastKeyEntry
833 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
834 // We have seen two identical key downs in a row which indicates that the device
835 // driver is automatically generating key repeats itself. We take note of the
836 // repeat here, but we disable our own next key repeat timer since it is clear that
837 // we will not need to synthesize key repeats ourselves.
838 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
839 resetKeyRepeatLocked();
840 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
841 } else {
842 // Not a repeat. Save key down state in case we do see a repeat later.
843 resetKeyRepeatLocked();
844 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
845 }
846 mKeyRepeatState.lastKeyEntry = entry;
847 entry->refCount += 1;
848 } else if (! entry->syntheticRepeat) {
849 resetKeyRepeatLocked();
850 }
851
852 if (entry->repeatCount == 1) {
853 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
854 } else {
855 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
856 }
857
858 entry->dispatchInProgress = true;
859
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800860 logOutboundKeyDetails("dispatchKey - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800861 }
862
863 // Handle case where the policy asked us to try again later last time.
864 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
865 if (currentTime < entry->interceptKeyWakeupTime) {
866 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
867 *nextWakeupTime = entry->interceptKeyWakeupTime;
868 }
869 return false; // wait until next wakeup
870 }
871 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
872 entry->interceptKeyWakeupTime = 0;
873 }
874
875 // Give the policy a chance to intercept the key.
876 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
877 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
878 CommandEntry* commandEntry = postCommandLocked(
879 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +0800880 sp<InputWindowHandle> focusedWindowHandle =
881 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(entry));
882 if (focusedWindowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -0700883 commandEntry->inputChannel =
884 getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800885 }
886 commandEntry->keyEntry = entry;
887 entry->refCount += 1;
888 return false; // wait for the command to run
889 } else {
890 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
891 }
892 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
893 if (*dropReason == DROP_REASON_NOT_DROPPED) {
894 *dropReason = DROP_REASON_POLICY;
895 }
896 }
897
898 // Clean up if dropping the event.
899 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800900 setInjectionResult(entry, *dropReason == DROP_REASON_POLICY
Michael Wrightd02c5b62014-02-10 15:10:22 -0800901 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800902 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800903 return true;
904 }
905
906 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800907 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800908 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
909 entry, inputTargets, nextWakeupTime);
910 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
911 return false;
912 }
913
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800914 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800915 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
916 return true;
917 }
918
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800919 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +0000920 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800921
922 // Dispatch the key.
923 dispatchEventLocked(currentTime, entry, inputTargets);
924 return true;
925}
926
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800927void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800928#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100929 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
930 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +0800931 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800932 prefix,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100933 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800934 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Arthur Hung82a4cad2018-11-15 12:10:30 +0800935 entry->repeatCount, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800936#endif
937}
938
939bool InputDispatcher::dispatchMotionLocked(
940 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000941 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800942 // Preprocessing.
943 if (! entry->dispatchInProgress) {
944 entry->dispatchInProgress = true;
945
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800946 logOutboundMotionDetails("dispatchMotion - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800947 }
948
949 // Clean up if dropping the event.
950 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800951 setInjectionResult(entry, *dropReason == DROP_REASON_POLICY
Michael Wrightd02c5b62014-02-10 15:10:22 -0800952 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
953 return true;
954 }
955
956 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
957
958 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800959 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800960
961 bool conflictingPointerActions = false;
962 int32_t injectionResult;
963 if (isPointerEvent) {
964 // Pointer event. (eg. touchscreen)
965 injectionResult = findTouchedWindowTargetsLocked(currentTime,
966 entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
967 } else {
968 // Non touch event. (eg. trackball)
969 injectionResult = findFocusedWindowTargetsLocked(currentTime,
970 entry, inputTargets, nextWakeupTime);
971 }
972 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
973 return false;
974 }
975
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800976 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800977 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +0100978 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
979 CancelationOptions::Mode mode(isPointerEvent ?
980 CancelationOptions::CANCEL_POINTER_EVENTS :
981 CancelationOptions::CANCEL_NON_POINTER_EVENTS);
982 CancelationOptions options(mode, "input event injection failed");
983 synthesizeCancelationEventsForMonitorsLocked(options);
984 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985 return true;
986 }
987
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800988 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +0000989 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800990
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800991 if (isPointerEvent) {
992 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
993 if (stateIndex >= 0) {
994 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800995 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800996 // The event has gone through these portal windows, so we add monitoring targets of
997 // the corresponding displays as well.
998 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800999 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001000 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001001 -windowInfo->frameLeft, -windowInfo->frameTop);
1002 }
1003 }
1004 }
1005 }
1006
Michael Wrightd02c5b62014-02-10 15:10:22 -08001007 // Dispatch the motion.
1008 if (conflictingPointerActions) {
1009 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
1010 "conflicting pointer actions");
1011 synthesizeCancelationEventsForAllConnectionsLocked(options);
1012 }
1013 dispatchEventLocked(currentTime, entry, inputTargets);
1014 return true;
1015}
1016
1017
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001018void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001019#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001020 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1021 ", policyFlags=0x%x, "
Michael Wright7b159c92015-05-14 14:48:03 +01001022 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1023 "metaState=0x%x, buttonState=0x%x,"
Arthur Hung82a4cad2018-11-15 12:10:30 +08001024 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001025 prefix,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001026 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001027 entry->action, entry->actionButton, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001028 entry->metaState, entry->buttonState,
1029 entry->edgeFlags, entry->xPrecision, entry->yPrecision,
Arthur Hung82a4cad2018-11-15 12:10:30 +08001030 entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001031
1032 for (uint32_t i = 0; i < entry->pointerCount; i++) {
1033 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1034 "x=%f, y=%f, pressure=%f, size=%f, "
1035 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001036 "orientation=%f",
Michael Wrightd02c5b62014-02-10 15:10:22 -08001037 i, entry->pointerProperties[i].id,
1038 entry->pointerProperties[i].toolType,
1039 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1040 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1041 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1042 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1043 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1044 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1045 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1046 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001047 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001048 }
1049#endif
1050}
1051
1052void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001053 EventEntry* eventEntry, const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001054 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001055#if DEBUG_DISPATCH_CYCLE
1056 ALOGD("dispatchEventToCurrentInputTargets");
1057#endif
1058
1059 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1060
1061 pokeUserActivityLocked(eventEntry);
1062
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001063 for (const InputTarget& inputTarget : inputTargets) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001064 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
1065 if (connectionIndex >= 0) {
1066 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1067 prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
1068 } else {
1069#if DEBUG_FOCUS
1070 ALOGD("Dropping event delivery to target with channel '%s' because it "
1071 "is no longer registered with the input dispatcher.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001072 inputTarget.inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001073#endif
1074 }
1075 }
1076}
1077
1078int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
1079 const EventEntry* entry,
1080 const sp<InputApplicationHandle>& applicationHandle,
1081 const sp<InputWindowHandle>& windowHandle,
1082 nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001083 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001084 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
1085#if DEBUG_FOCUS
1086 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1087#endif
1088 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1089 mInputTargetWaitStartTime = currentTime;
1090 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1091 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001092 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001093 }
1094 } else {
1095 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1096#if DEBUG_FOCUS
1097 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001098 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001099 reason);
1100#endif
1101 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001102 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001103 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001104 } else if (applicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001105 timeout = applicationHandle->getDispatchingTimeout(
1106 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1107 } else {
1108 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1109 }
1110
1111 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1112 mInputTargetWaitStartTime = currentTime;
1113 mInputTargetWaitTimeoutTime = currentTime + timeout;
1114 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001115 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001116
Yi Kong9b14ac62018-07-17 13:48:38 -07001117 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001118 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001119 }
Robert Carr740167f2018-10-11 19:03:41 -07001120 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1121 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001122 }
1123 }
1124 }
1125
1126 if (mInputTargetWaitTimeoutExpired) {
1127 return INPUT_EVENT_INJECTION_TIMED_OUT;
1128 }
1129
1130 if (currentTime >= mInputTargetWaitTimeoutTime) {
1131 onANRLocked(currentTime, applicationHandle, windowHandle,
1132 entry->eventTime, mInputTargetWaitStartTime, reason);
1133
1134 // Force poll loop to wake up immediately on next iteration once we get the
1135 // ANR response back from the policy.
1136 *nextWakeupTime = LONG_LONG_MIN;
1137 return INPUT_EVENT_INJECTION_PENDING;
1138 } else {
1139 // Force poll loop to wake up when timeout is due.
1140 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1141 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1142 }
1143 return INPUT_EVENT_INJECTION_PENDING;
1144 }
1145}
1146
Robert Carr803535b2018-08-02 16:38:15 -07001147void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1148 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1149 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1150 state.removeWindowByToken(token);
1151 }
1152}
1153
Michael Wrightd02c5b62014-02-10 15:10:22 -08001154void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1155 const sp<InputChannel>& inputChannel) {
1156 if (newTimeout > 0) {
1157 // Extend the timeout.
1158 mInputTargetWaitTimeoutTime = now() + newTimeout;
1159 } else {
1160 // Give up.
1161 mInputTargetWaitTimeoutExpired = true;
1162
1163 // Input state will not be realistic. Mark it out of sync.
1164 if (inputChannel.get()) {
1165 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1166 if (connectionIndex >= 0) {
1167 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
Robert Carr803535b2018-08-02 16:38:15 -07001168 sp<IBinder> token = connection->inputChannel->getToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001169
Robert Carr803535b2018-08-02 16:38:15 -07001170 if (token != nullptr) {
1171 removeWindowByTokenLocked(token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001172 }
1173
1174 if (connection->status == Connection::STATUS_NORMAL) {
1175 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1176 "application not responding");
1177 synthesizeCancelationEventsForConnectionLocked(connection, options);
1178 }
1179 }
1180 }
1181 }
1182}
1183
1184nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
1185 nsecs_t currentTime) {
1186 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1187 return currentTime - mInputTargetWaitStartTime;
1188 }
1189 return 0;
1190}
1191
1192void InputDispatcher::resetANRTimeoutsLocked() {
1193#if DEBUG_FOCUS
1194 ALOGD("Resetting ANR timeouts.");
1195#endif
1196
1197 // Reset input target wait timeout.
1198 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001199 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001200}
1201
Tiger Huang721e26f2018-07-24 22:26:19 +08001202/**
1203 * Get the display id that the given event should go to. If this event specifies a valid display id,
1204 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1205 * Focused display is the display that the user most recently interacted with.
1206 */
1207int32_t InputDispatcher::getTargetDisplayId(const EventEntry* entry) {
1208 int32_t displayId;
1209 switch (entry->type) {
1210 case EventEntry::TYPE_KEY: {
1211 const KeyEntry* typedEntry = static_cast<const KeyEntry*>(entry);
1212 displayId = typedEntry->displayId;
1213 break;
1214 }
1215 case EventEntry::TYPE_MOTION: {
1216 const MotionEntry* typedEntry = static_cast<const MotionEntry*>(entry);
1217 displayId = typedEntry->displayId;
1218 break;
1219 }
1220 default: {
1221 ALOGE("Unsupported event type '%" PRId32 "' for target display.", entry->type);
1222 return ADISPLAY_ID_NONE;
1223 }
1224 }
1225 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1226}
1227
Michael Wrightd02c5b62014-02-10 15:10:22 -08001228int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001229 const EventEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001230 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001231 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001232
Tiger Huang721e26f2018-07-24 22:26:19 +08001233 int32_t displayId = getTargetDisplayId(entry);
1234 sp<InputWindowHandle> focusedWindowHandle =
1235 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1236 sp<InputApplicationHandle> focusedApplicationHandle =
1237 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1238
Michael Wrightd02c5b62014-02-10 15:10:22 -08001239 // If there is no currently focused window and no focused application
1240 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001241 if (focusedWindowHandle == nullptr) {
1242 if (focusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001243 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001244 focusedApplicationHandle, nullptr, nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001245 "Waiting because no window has focus but there is a "
1246 "focused application that may eventually add a window "
1247 "when it finishes starting up.");
1248 goto Unresponsive;
1249 }
1250
Arthur Hung3b413f22018-10-26 18:05:34 +08001251 ALOGI("Dropping event because there is no focused window or focused application in display "
1252 "%" PRId32 ".", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001253 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1254 goto Failed;
1255 }
1256
1257 // Check permissions.
Tiger Huang721e26f2018-07-24 22:26:19 +08001258 if (!checkInjectionPermission(focusedWindowHandle, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001259 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1260 goto Failed;
1261 }
1262
Jeff Brownffb49772014-10-10 19:01:34 -07001263 // Check whether the window is ready for more input.
1264 reason = checkWindowReadyForMoreInputLocked(currentTime,
Tiger Huang721e26f2018-07-24 22:26:19 +08001265 focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001266 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001267 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001268 focusedApplicationHandle, focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001269 goto Unresponsive;
1270 }
1271
1272 // Success! Output targets.
1273 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001274 addWindowTargetLocked(focusedWindowHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001275 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
1276 inputTargets);
1277
1278 // Done.
1279Failed:
1280Unresponsive:
1281 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001282 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001283#if DEBUG_FOCUS
1284 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1285 "timeSpentWaitingForApplication=%0.1fms",
1286 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1287#endif
1288 return injectionResult;
1289}
1290
1291int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001292 const MotionEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001293 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001294 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001295 enum InjectionPermission {
1296 INJECTION_PERMISSION_UNKNOWN,
1297 INJECTION_PERMISSION_GRANTED,
1298 INJECTION_PERMISSION_DENIED
1299 };
1300
Michael Wrightd02c5b62014-02-10 15:10:22 -08001301 // For security reasons, we defer updating the touch state until we are sure that
1302 // event injection will be allowed.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001303 int32_t displayId = entry->displayId;
1304 int32_t action = entry->action;
1305 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1306
1307 // Update the touch state as needed based on the properties of the touch event.
1308 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1309 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1310 sp<InputWindowHandle> newHoverWindowHandle;
1311
Jeff Brownf086ddb2014-02-11 14:28:48 -08001312 // Copy current touch state into mTempTouchState.
1313 // This state is always reset at the end of this function, so if we don't find state
1314 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001315 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001316 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1317 if (oldStateIndex >= 0) {
1318 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1319 mTempTouchState.copyFrom(*oldState);
1320 }
1321
1322 bool isSplit = mTempTouchState.split;
1323 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0
1324 && (mTempTouchState.deviceId != entry->deviceId
1325 || mTempTouchState.source != entry->source
1326 || mTempTouchState.displayId != displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001327 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1328 || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1329 || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1330 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
1331 || maskedAction == AMOTION_EVENT_ACTION_SCROLL
1332 || isHoverAction);
Garfield Tan00f511d2019-06-12 16:55:40 -07001333 const bool isFromMouse = entry->source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001334 bool wrongDevice = false;
1335 if (newGesture) {
1336 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001337 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001338#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001339 ALOGD("Dropping event because a pointer for a different device is already down "
1340 "in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001341#endif
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001342 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001343 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1344 switchedDevice = false;
1345 wrongDevice = true;
1346 goto Failed;
1347 }
1348 mTempTouchState.reset();
1349 mTempTouchState.down = down;
1350 mTempTouchState.deviceId = entry->deviceId;
1351 mTempTouchState.source = entry->source;
1352 mTempTouchState.displayId = displayId;
1353 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001354 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
1355#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001356 ALOGI("Dropping move event because a pointer for a different device is already active "
1357 "in display %" PRId32, displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001358#endif
1359 // TODO: test multiple simultaneous input streams.
1360 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1361 switchedDevice = false;
1362 wrongDevice = true;
1363 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001364 }
1365
1366 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1367 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1368
Garfield Tan00f511d2019-06-12 16:55:40 -07001369 int32_t x;
1370 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001371 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001372 // Always dispatch mouse events to cursor position.
1373 if (isFromMouse) {
1374 x = int32_t(entry->xCursorPosition);
1375 y = int32_t(entry->yCursorPosition);
1376 } else {
1377 x = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1378 y = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
1379 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001380 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001381 sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +00001382 displayId, x, y, isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
1383
1384 std::vector<TouchedMonitor> newGestureMonitors = isDown
1385 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1386 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001387
Michael Wrightd02c5b62014-02-10 15:10:22 -08001388 // Figure out whether splitting will be allowed for this window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001389 if (newTouchedWindowHandle != nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001390 && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001391 // New window supports splitting, but we should never split mouse events.
1392 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001393 } else if (isSplit) {
1394 // New window does not support splitting but we have already split events.
1395 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001396 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001397 }
1398
1399 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001400 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001401 // Try to assign the pointer to the first foreground window we find, if there is one.
1402 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001403 }
1404
1405 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1406 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
1407 "(%d, %d) in display %" PRId32 ".", x, y, displayId);
1408 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1409 goto Failed;
1410 }
1411
1412 if (newTouchedWindowHandle != nullptr) {
1413 // Set target flags.
1414 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1415 if (isSplit) {
1416 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001417 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001418 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1419 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1420 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1421 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1422 }
1423
1424 // Update hover state.
1425 if (isHoverAction) {
1426 newHoverWindowHandle = newTouchedWindowHandle;
1427 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1428 newHoverWindowHandle = mLastHoverWindowHandle;
1429 }
1430
1431 // Update the temporary touch state.
1432 BitSet32 pointerIds;
1433 if (isSplit) {
1434 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1435 pointerIds.markBit(pointerId);
1436 }
1437 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001438 }
1439
Michael Wright3dd60e22019-03-27 22:06:44 +00001440 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001441 } else {
1442 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1443
1444 // If the pointer is not currently down, then ignore the event.
1445 if (! mTempTouchState.down) {
1446#if DEBUG_FOCUS
1447 ALOGD("Dropping event because the pointer is not down or we previously "
Arthur Hung3b413f22018-10-26 18:05:34 +08001448 "dropped the pointer down event in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001449#endif
1450 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1451 goto Failed;
1452 }
1453
1454 // Check whether touches should slip outside of the current foreground window.
1455 if (maskedAction == AMOTION_EVENT_ACTION_MOVE
1456 && entry->pointerCount == 1
1457 && mTempTouchState.isSlippery()) {
1458 int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1459 int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
1460
1461 sp<InputWindowHandle> oldTouchedWindowHandle =
1462 mTempTouchState.getFirstForegroundWindowHandle();
1463 sp<InputWindowHandle> newTouchedWindowHandle =
1464 findTouchedWindowAtLocked(displayId, x, y);
1465 if (oldTouchedWindowHandle != newTouchedWindowHandle
Michael Wright3dd60e22019-03-27 22:06:44 +00001466 && oldTouchedWindowHandle != nullptr
Yi Kong9b14ac62018-07-17 13:48:38 -07001467 && newTouchedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001468#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001469 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001470 oldTouchedWindowHandle->getName().c_str(),
Arthur Hung3b413f22018-10-26 18:05:34 +08001471 newTouchedWindowHandle->getName().c_str(),
1472 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001473#endif
1474 // Make a slippery exit from the old window.
1475 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1476 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
1477
1478 // Make a slippery entrance into the new window.
1479 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1480 isSplit = true;
1481 }
1482
1483 int32_t targetFlags = InputTarget::FLAG_FOREGROUND
1484 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
1485 if (isSplit) {
1486 targetFlags |= InputTarget::FLAG_SPLIT;
1487 }
1488 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1489 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1490 }
1491
1492 BitSet32 pointerIds;
1493 if (isSplit) {
1494 pointerIds.markBit(entry->pointerProperties[0].id);
1495 }
1496 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1497 }
1498 }
1499 }
1500
1501 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1502 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001503 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001504#if DEBUG_HOVER
1505 ALOGD("Sending hover exit event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001506 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001507#endif
1508 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1509 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
1510 }
1511
1512 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001513 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001514#if DEBUG_HOVER
1515 ALOGD("Sending hover enter event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001516 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001517#endif
1518 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1519 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
1520 }
1521 }
1522
1523 // Check permission to inject into all touched foreground windows and ensure there
1524 // is at least one touched foreground window.
1525 {
1526 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001527 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001528 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1529 haveForegroundWindow = true;
1530 if (! checkInjectionPermission(touchedWindow.windowHandle,
1531 entry->injectionState)) {
1532 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1533 injectionPermission = INJECTION_PERMISSION_DENIED;
1534 goto Failed;
1535 }
1536 }
1537 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001538 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1539 if (!haveForegroundWindow && !hasGestureMonitor) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001540#if DEBUG_FOCUS
Michael Wright3dd60e22019-03-27 22:06:44 +00001541 ALOGD("Dropping event because there is no touched foreground window in display %"
1542 PRId32 " or gesture monitor to receive it.", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001543#endif
1544 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1545 goto Failed;
1546 }
1547
1548 // Permission granted to injection into all touched foreground windows.
1549 injectionPermission = INJECTION_PERMISSION_GRANTED;
1550 }
1551
1552 // Check whether windows listening for outside touches are owned by the same UID. If it is
1553 // set the policy flag that we will not reveal coordinate information to this window.
1554 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1555 sp<InputWindowHandle> foregroundWindowHandle =
1556 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001557 if (foregroundWindowHandle) {
1558 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1559 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1560 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1561 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1562 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1563 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
1564 InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
1565 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001566 }
1567 }
1568 }
1569 }
1570
1571 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001572 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001573 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001574 // Check whether the window is ready for more input.
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001575 std::string reason = checkWindowReadyForMoreInputLocked(currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001576 touchedWindow.windowHandle, entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001577 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001578 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Yi Kong9b14ac62018-07-17 13:48:38 -07001579 nullptr, touchedWindow.windowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001580 goto Unresponsive;
1581 }
1582 }
1583 }
1584
1585 // If this is the first pointer going down and the touched window has a wallpaper
1586 // then also add the touched wallpaper windows so they are locked in for the duration
1587 // of the touch gesture.
1588 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1589 // engine only supports touch events. We would need to add a mechanism similar
1590 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1591 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1592 sp<InputWindowHandle> foregroundWindowHandle =
1593 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001594 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001595 const std::vector<sp<InputWindowHandle>> windowHandles =
1596 getWindowHandlesLocked(displayId);
1597 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001598 const InputWindowInfo* info = windowHandle->getInfo();
1599 if (info->displayId == displayId
1600 && windowHandle->getInfo()->layoutParamsType
1601 == InputWindowInfo::TYPE_WALLPAPER) {
1602 mTempTouchState.addOrUpdateWindow(windowHandle,
1603 InputTarget::FLAG_WINDOW_IS_OBSCURED
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001604 | InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605 | InputTarget::FLAG_DISPATCH_AS_IS,
1606 BitSet32(0));
1607 }
1608 }
1609 }
1610 }
1611
1612 // Success! Output targets.
1613 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1614
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001615 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001616 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
1617 touchedWindow.pointerIds, inputTargets);
1618 }
1619
Michael Wright3dd60e22019-03-27 22:06:44 +00001620 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1621 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
1622 touchedMonitor.yOffset, inputTargets);
1623 }
1624
Michael Wrightd02c5b62014-02-10 15:10:22 -08001625 // Drop the outside or hover touch windows since we will not care about them
1626 // in the next iteration.
1627 mTempTouchState.filterNonAsIsTouchWindows();
1628
1629Failed:
1630 // Check injection permission once and for all.
1631 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001632 if (checkInjectionPermission(nullptr, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001633 injectionPermission = INJECTION_PERMISSION_GRANTED;
1634 } else {
1635 injectionPermission = INJECTION_PERMISSION_DENIED;
1636 }
1637 }
1638
1639 // Update final pieces of touch state if the injector had permission.
1640 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1641 if (!wrongDevice) {
1642 if (switchedDevice) {
1643#if DEBUG_FOCUS
1644 ALOGD("Conflicting pointer actions: Switched to a different device.");
1645#endif
1646 *outConflictingPointerActions = true;
1647 }
1648
1649 if (isHoverAction) {
1650 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001651 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001652#if DEBUG_FOCUS
1653 ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
1654#endif
1655 *outConflictingPointerActions = true;
1656 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001657 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001658 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1659 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08001660 mTempTouchState.deviceId = entry->deviceId;
1661 mTempTouchState.source = entry->source;
1662 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001663 }
1664 } else if (maskedAction == AMOTION_EVENT_ACTION_UP
1665 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1666 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001667 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001668 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1669 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001670 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001671#if DEBUG_FOCUS
1672 ALOGD("Conflicting pointer actions: Down received while already down.");
1673#endif
1674 *outConflictingPointerActions = true;
1675 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001676 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1677 // One pointer went up.
1678 if (isSplit) {
1679 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1680 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1681
1682 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001683 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001684 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1685 touchedWindow.pointerIds.clearBit(pointerId);
1686 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001687 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001688 continue;
1689 }
1690 }
1691 i += 1;
1692 }
1693 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001694 }
1695
1696 // Save changes unless the action was scroll in which case the temporary touch
1697 // state was only valid for this one action.
1698 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1699 if (mTempTouchState.displayId >= 0) {
1700 if (oldStateIndex >= 0) {
1701 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1702 } else {
1703 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1704 }
1705 } else if (oldStateIndex >= 0) {
1706 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1707 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001708 }
1709
1710 // Update hover state.
1711 mLastHoverWindowHandle = newHoverWindowHandle;
1712 }
1713 } else {
1714#if DEBUG_FOCUS
1715 ALOGD("Not updating touch focus because injection was denied.");
1716#endif
1717 }
1718
1719Unresponsive:
1720 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1721 mTempTouchState.reset();
1722
1723 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001724 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001725#if DEBUG_FOCUS
1726 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1727 "timeSpentWaitingForApplication=%0.1fms",
1728 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1729#endif
1730 return injectionResult;
1731}
1732
1733void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001734 int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets) {
Arthur Hungceeb5d72018-12-05 16:14:18 +08001735 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1736 if (inputChannel == nullptr) {
1737 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1738 return;
1739 }
1740
Michael Wrightd02c5b62014-02-10 15:10:22 -08001741 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001742 InputTarget target;
Arthur Hungceeb5d72018-12-05 16:14:18 +08001743 target.inputChannel = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001744 target.flags = targetFlags;
1745 target.xOffset = - windowInfo->frameLeft;
1746 target.yOffset = - windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08001747 target.globalScaleFactor = windowInfo->globalScaleFactor;
1748 target.windowXScale = windowInfo->windowXScale;
1749 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001750 target.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001751 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001752}
1753
Michael Wright3dd60e22019-03-27 22:06:44 +00001754void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
1755 int32_t displayId, float xOffset, float yOffset) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001756
Michael Wright3dd60e22019-03-27 22:06:44 +00001757 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1758 mGlobalMonitorsByDisplay.find(displayId);
1759
1760 if (it != mGlobalMonitorsByDisplay.end()) {
1761 const std::vector<Monitor>& monitors = it->second;
1762 for (const Monitor& monitor : monitors) {
1763 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001764 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001765 }
1766}
1767
Michael Wright3dd60e22019-03-27 22:06:44 +00001768void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor,
1769 float xOffset, float yOffset, std::vector<InputTarget>& inputTargets) {
1770 InputTarget target;
1771 target.inputChannel = monitor.inputChannel;
1772 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1773 target.xOffset = xOffset;
1774 target.yOffset = yOffset;
1775 target.pointerIds.clear();
1776 target.globalScaleFactor = 1.0f;
1777 inputTargets.push_back(target);
1778}
1779
Michael Wrightd02c5b62014-02-10 15:10:22 -08001780bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
1781 const InjectionState* injectionState) {
1782 if (injectionState
Yi Kong9b14ac62018-07-17 13:48:38 -07001783 && (windowHandle == nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001784 || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
1785 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001786 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001787 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
1788 "owned by uid %d",
1789 injectionState->injectorPid, injectionState->injectorUid,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001790 windowHandle->getName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001791 windowHandle->getInfo()->ownerUid);
1792 } else {
1793 ALOGW("Permission denied: injecting event from pid %d uid %d",
1794 injectionState->injectorPid, injectionState->injectorUid);
1795 }
1796 return false;
1797 }
1798 return true;
1799}
1800
1801bool InputDispatcher::isWindowObscuredAtPointLocked(
1802 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
1803 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001804 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1805 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001806 if (otherHandle == windowHandle) {
1807 break;
1808 }
1809
1810 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1811 if (otherInfo->displayId == displayId
1812 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1813 && otherInfo->frameContainsPoint(x, y)) {
1814 return true;
1815 }
1816 }
1817 return false;
1818}
1819
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001820
1821bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1822 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001823 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001824 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001825 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001826 if (otherHandle == windowHandle) {
1827 break;
1828 }
1829
1830 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1831 if (otherInfo->displayId == displayId
1832 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1833 && otherInfo->overlaps(windowInfo)) {
1834 return true;
1835 }
1836 }
1837 return false;
1838}
1839
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001840std::string InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001841 const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry,
1842 const char* targetType) {
1843 // If the window is paused then keep waiting.
1844 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001845 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001846 }
1847
1848 // If the window's connection is not registered then keep waiting.
Robert Carr5c8a0262018-10-03 16:30:44 -07001849 ssize_t connectionIndex = getConnectionIndexLocked(
1850 getInputChannelLocked(windowHandle->getToken()));
Jeff Brownffb49772014-10-10 19:01:34 -07001851 if (connectionIndex < 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001852 return StringPrintf("Waiting because the %s window's input channel is not "
Jeff Brownffb49772014-10-10 19:01:34 -07001853 "registered with the input dispatcher. The window may be in the process "
1854 "of being removed.", targetType);
1855 }
1856
1857 // If the connection is dead then keep waiting.
1858 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1859 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001860 return StringPrintf("Waiting because the %s window's input connection is %s."
Jeff Brownffb49772014-10-10 19:01:34 -07001861 "The window may be in the process of being removed.", targetType,
1862 connection->getStatusLabel());
1863 }
1864
1865 // If the connection is backed up then keep waiting.
1866 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001867 return StringPrintf("Waiting because the %s window's input channel is full. "
Jeff Brownffb49772014-10-10 19:01:34 -07001868 "Outbound queue length: %d. Wait queue length: %d.",
1869 targetType, connection->outboundQueue.count(), connection->waitQueue.count());
1870 }
1871
1872 // Ensure that the dispatch queues aren't too far backed up for this event.
1873 if (eventEntry->type == EventEntry::TYPE_KEY) {
1874 // If the event is a key event, then we must wait for all previous events to
1875 // complete before delivering it because previous events may have the
1876 // side-effect of transferring focus to a different window and we want to
1877 // ensure that the following keys are sent to the new window.
1878 //
1879 // Suppose the user touches a button in a window then immediately presses "A".
1880 // If the button causes a pop-up window to appear then we want to ensure that
1881 // the "A" key is delivered to the new pop-up window. This is because users
1882 // often anticipate pending UI changes when typing on a keyboard.
1883 // To obtain this behavior, we must serialize key events with respect to all
1884 // prior input events.
1885 if (!connection->outboundQueue.isEmpty() || !connection->waitQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001886 return StringPrintf("Waiting to send key event because the %s window has not "
Jeff Brownffb49772014-10-10 19:01:34 -07001887 "finished processing all of the input events that were previously "
1888 "delivered to it. Outbound queue length: %d. Wait queue length: %d.",
1889 targetType, connection->outboundQueue.count(), connection->waitQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001890 }
Jeff Brownffb49772014-10-10 19:01:34 -07001891 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001892 // Touch events can always be sent to a window immediately because the user intended
1893 // to touch whatever was visible at the time. Even if focus changes or a new
1894 // window appears moments later, the touch event was meant to be delivered to
1895 // whatever window happened to be on screen at the time.
1896 //
1897 // Generic motion events, such as trackball or joystick events are a little trickier.
1898 // Like key events, generic motion events are delivered to the focused window.
1899 // Unlike key events, generic motion events don't tend to transfer focus to other
1900 // windows and it is not important for them to be serialized. So we prefer to deliver
1901 // generic motion events as soon as possible to improve efficiency and reduce lag
1902 // through batching.
1903 //
1904 // The one case where we pause input event delivery is when the wait queue is piling
1905 // up with lots of events because the application is not responding.
1906 // This condition ensures that ANRs are detected reliably.
1907 if (!connection->waitQueue.isEmpty()
1908 && currentTime >= connection->waitQueue.head->deliveryTime
1909 + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001910 return StringPrintf("Waiting to send non-key event because the %s window has not "
Jeff Brownffb49772014-10-10 19:01:34 -07001911 "finished processing certain input events that were delivered to it over "
1912 "%0.1fms ago. Wait queue length: %d. Wait queue head age: %0.1fms.",
1913 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
1914 connection->waitQueue.count(),
1915 (currentTime - connection->waitQueue.head->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001916 }
1917 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001918 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001919}
1920
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001921std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08001922 const sp<InputApplicationHandle>& applicationHandle,
1923 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001924 if (applicationHandle != nullptr) {
1925 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001926 std::string label(applicationHandle->getName());
1927 label += " - ";
1928 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001929 return label;
1930 } else {
1931 return applicationHandle->getName();
1932 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001933 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001934 return windowHandle->getName();
1935 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001936 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001937 }
1938}
1939
1940void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001941 int32_t displayId = getTargetDisplayId(eventEntry);
1942 sp<InputWindowHandle> focusedWindowHandle =
1943 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1944 if (focusedWindowHandle != nullptr) {
1945 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001946 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
1947#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001948 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001949#endif
1950 return;
1951 }
1952 }
1953
1954 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
1955 switch (eventEntry->type) {
1956 case EventEntry::TYPE_MOTION: {
1957 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1958 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1959 return;
1960 }
1961
1962 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
1963 eventType = USER_ACTIVITY_EVENT_TOUCH;
1964 }
1965 break;
1966 }
1967 case EventEntry::TYPE_KEY: {
1968 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1969 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1970 return;
1971 }
1972 eventType = USER_ACTIVITY_EVENT_BUTTON;
1973 break;
1974 }
1975 }
1976
1977 CommandEntry* commandEntry = postCommandLocked(
1978 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1979 commandEntry->eventTime = eventEntry->eventTime;
1980 commandEntry->userActivityEventType = eventType;
1981}
1982
1983void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1984 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001985 if (ATRACE_ENABLED()) {
1986 std::string message = StringPrintf(
1987 "prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
1988 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
1989 ATRACE_NAME(message.c_str());
1990 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001991#if DEBUG_DISPATCH_CYCLE
1992 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Robert Carre07e1032018-11-26 12:55:53 -08001993 "xOffset=%f, yOffset=%f, globalScaleFactor=%f, "
1994 "windowScaleFactor=(%f, %f), pointerIds=0x%x",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08001995 connection->getInputChannelName().c_str(), inputTarget->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001996 inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08001997 inputTarget->globalScaleFactor,
1998 inputTarget->windowXScale, inputTarget->windowYScale,
1999 inputTarget->pointerIds.value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002000#endif
2001
2002 // Skip this event if the connection status is not normal.
2003 // We don't want to enqueue additional outbound events if the connection is broken.
2004 if (connection->status != Connection::STATUS_NORMAL) {
2005#if DEBUG_DISPATCH_CYCLE
2006 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002007 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002008#endif
2009 return;
2010 }
2011
2012 // Split a motion event if needed.
2013 if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
2014 ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
2015
2016 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
2017 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
2018 MotionEntry* splitMotionEntry = splitMotionEvent(
2019 originalMotionEntry, inputTarget->pointerIds);
2020 if (!splitMotionEntry) {
2021 return; // split event was dropped
2022 }
2023#if DEBUG_FOCUS
2024 ALOGD("channel '%s' ~ Split motion event.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002025 connection->getInputChannelName().c_str());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002026 logOutboundMotionDetails(" ", splitMotionEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002027#endif
2028 enqueueDispatchEntriesLocked(currentTime, connection,
2029 splitMotionEntry, inputTarget);
2030 splitMotionEntry->release();
2031 return;
2032 }
2033 }
2034
2035 // Not splitting. Enqueue dispatch entries for the event as is.
2036 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2037}
2038
2039void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
2040 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002041 if (ATRACE_ENABLED()) {
2042 std::string message = StringPrintf(
2043 "enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2044 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
2045 ATRACE_NAME(message.c_str());
2046 }
2047
Michael Wrightd02c5b62014-02-10 15:10:22 -08002048 bool wasEmpty = connection->outboundQueue.isEmpty();
2049
2050 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002051 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002052 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002053 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002054 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002055 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002056 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002057 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002058 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002059 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002060 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002061 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002062 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
2063
2064 // If the outbound queue was previously empty, start the dispatch cycle going.
2065 if (wasEmpty && !connection->outboundQueue.isEmpty()) {
2066 startDispatchCycleLocked(currentTime, connection);
2067 }
2068}
2069
chaviw8c9cf542019-03-25 13:02:48 -07002070void InputDispatcher::enqueueDispatchEntryLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002071 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
2072 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002073 if (ATRACE_ENABLED()) {
2074 std::string message = StringPrintf(
2075 "enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2076 connection->getInputChannelName().c_str(),
2077 dispatchModeToString(dispatchMode).c_str());
2078 ATRACE_NAME(message.c_str());
2079 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002080 int32_t inputTargetFlags = inputTarget->flags;
2081 if (!(inputTargetFlags & dispatchMode)) {
2082 return;
2083 }
2084 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2085
2086 // This is a new event.
2087 // Enqueue a new dispatch entry onto the outbound queue for this connection.
2088 DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
2089 inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08002090 inputTarget->globalScaleFactor, inputTarget->windowXScale,
2091 inputTarget->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002092
2093 // Apply target flags and update the connection's input state.
2094 switch (eventEntry->type) {
2095 case EventEntry::TYPE_KEY: {
2096 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2097 dispatchEntry->resolvedAction = keyEntry->action;
2098 dispatchEntry->resolvedFlags = keyEntry->flags;
2099
2100 if (!connection->inputState.trackKey(keyEntry,
2101 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2102#if DEBUG_DISPATCH_CYCLE
2103 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002104 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002105#endif
2106 delete dispatchEntry;
2107 return; // skip the inconsistent event
2108 }
2109 break;
2110 }
2111
2112 case EventEntry::TYPE_MOTION: {
2113 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2114 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2115 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2116 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2117 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2118 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2119 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2120 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2121 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2122 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2123 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2124 } else {
2125 dispatchEntry->resolvedAction = motionEntry->action;
2126 }
2127 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
2128 && !connection->inputState.isHovering(
2129 motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
2130#if DEBUG_DISPATCH_CYCLE
2131 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002132 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002133#endif
2134 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2135 }
2136
2137 dispatchEntry->resolvedFlags = motionEntry->flags;
2138 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2139 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2140 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002141 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2142 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2143 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002144
2145 if (!connection->inputState.trackMotion(motionEntry,
2146 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2147#if DEBUG_DISPATCH_CYCLE
2148 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002149 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002150#endif
2151 delete dispatchEntry;
2152 return; // skip the inconsistent event
2153 }
chaviw8c9cf542019-03-25 13:02:48 -07002154
chaviwfd6d3512019-03-25 13:23:49 -07002155 dispatchPointerDownOutsideFocus(motionEntry->source,
chaviw8c9cf542019-03-25 13:02:48 -07002156 dispatchEntry->resolvedAction, inputTarget->inputChannel->getToken());
2157
Michael Wrightd02c5b62014-02-10 15:10:22 -08002158 break;
2159 }
2160 }
2161
2162 // Remember that we are waiting for this dispatch to complete.
2163 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002164 incrementPendingForegroundDispatches(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002165 }
2166
2167 // Enqueue the dispatch entry.
2168 connection->outboundQueue.enqueueAtTail(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002169 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002170
2171}
2172
chaviwfd6d3512019-03-25 13:23:49 -07002173void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
chaviw8c9cf542019-03-25 13:02:48 -07002174 const sp<IBinder>& newToken) {
2175 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002176 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2177 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002178 return;
2179 }
2180
2181 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2182 if (inputWindowHandle == nullptr) {
2183 return;
2184 }
2185
chaviw8c9cf542019-03-25 13:02:48 -07002186 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002187 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002188
2189 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2190
2191 if (!hasFocusChanged) {
2192 return;
2193 }
2194
chaviwfd6d3512019-03-25 13:23:49 -07002195 CommandEntry* commandEntry = postCommandLocked(
2196 & InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
2197 commandEntry->newToken = newToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002198}
2199
2200void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
2201 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002202 if (ATRACE_ENABLED()) {
2203 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
2204 connection->getInputChannelName().c_str());
2205 ATRACE_NAME(message.c_str());
2206 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002207#if DEBUG_DISPATCH_CYCLE
2208 ALOGD("channel '%s' ~ startDispatchCycle",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002209 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002210#endif
2211
2212 while (connection->status == Connection::STATUS_NORMAL
2213 && !connection->outboundQueue.isEmpty()) {
2214 DispatchEntry* dispatchEntry = connection->outboundQueue.head;
2215 dispatchEntry->deliveryTime = currentTime;
2216
2217 // Publish the event.
2218 status_t status;
2219 EventEntry* eventEntry = dispatchEntry->eventEntry;
2220 switch (eventEntry->type) {
2221 case EventEntry::TYPE_KEY: {
2222 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2223
2224 // Publish the key event.
2225 status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002226 keyEntry->deviceId, keyEntry->source, keyEntry->displayId,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002227 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
2228 keyEntry->keyCode, keyEntry->scanCode,
2229 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
2230 keyEntry->eventTime);
2231 break;
2232 }
2233
2234 case EventEntry::TYPE_MOTION: {
2235 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2236
2237 PointerCoords scaledCoords[MAX_POINTERS];
2238 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2239
2240 // Set the X and Y offset depending on the input source.
Siarhei Vishniakou635cb712017-11-01 16:32:14 -07002241 float xOffset, yOffset;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002242 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
2243 && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
Robert Carre07e1032018-11-26 12:55:53 -08002244 float globalScaleFactor = dispatchEntry->globalScaleFactor;
2245 float wxs = dispatchEntry->windowXScale;
2246 float wys = dispatchEntry->windowYScale;
2247 xOffset = dispatchEntry->xOffset * wxs;
2248 yOffset = dispatchEntry->yOffset * wys;
2249 if (wxs != 1.0f || wys != 1.0f || globalScaleFactor != 1.0f) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002250 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002251 scaledCoords[i] = motionEntry->pointerCoords[i];
Robert Carre07e1032018-11-26 12:55:53 -08002252 scaledCoords[i].scale(globalScaleFactor, wxs, wys);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002253 }
2254 usingCoords = scaledCoords;
2255 }
2256 } else {
2257 xOffset = 0.0f;
2258 yOffset = 0.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002259
2260 // We don't want the dispatch target to know.
2261 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002262 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002263 scaledCoords[i].clear();
2264 }
2265 usingCoords = scaledCoords;
2266 }
2267 }
2268
2269 // Publish the motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002270 status =
2271 connection->inputPublisher
2272 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2273 motionEntry->source, motionEntry->displayId,
2274 dispatchEntry->resolvedAction,
2275 motionEntry->actionButton,
2276 dispatchEntry->resolvedFlags,
2277 motionEntry->edgeFlags, motionEntry->metaState,
2278 motionEntry->buttonState,
2279 motionEntry->classification, xOffset, yOffset,
2280 motionEntry->xPrecision, motionEntry->yPrecision,
2281 motionEntry->xCursorPosition,
2282 motionEntry->yCursorPosition, motionEntry->downTime,
2283 motionEntry->eventTime, motionEntry->pointerCount,
2284 motionEntry->pointerProperties, usingCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002285 break;
2286 }
2287
2288 default:
2289 ALOG_ASSERT(false);
2290 return;
2291 }
2292
2293 // Check the result.
2294 if (status) {
2295 if (status == WOULD_BLOCK) {
2296 if (connection->waitQueue.isEmpty()) {
2297 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
2298 "This is unexpected because the wait queue is empty, so the pipe "
2299 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002300 "event to it, status=%d", connection->getInputChannelName().c_str(),
2301 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002302 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2303 } else {
2304 // Pipe is full and we are waiting for the app to finish process some events
2305 // before sending more events to it.
2306#if DEBUG_DISPATCH_CYCLE
2307 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
2308 "waiting for the application to catch up",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002309 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002310#endif
2311 connection->inputPublisherBlocked = true;
2312 }
2313 } else {
2314 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002315 "status=%d", connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002316 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2317 }
2318 return;
2319 }
2320
2321 // Re-enqueue the event on the wait queue.
2322 connection->outboundQueue.dequeue(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002323 traceOutboundQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002324 connection->waitQueue.enqueueAtTail(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002325 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002326 }
2327}
2328
2329void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
2330 const sp<Connection>& connection, uint32_t seq, bool handled) {
2331#if DEBUG_DISPATCH_CYCLE
2332 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002333 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002334#endif
2335
2336 connection->inputPublisherBlocked = false;
2337
2338 if (connection->status == Connection::STATUS_BROKEN
2339 || connection->status == Connection::STATUS_ZOMBIE) {
2340 return;
2341 }
2342
2343 // Notify other system components and prepare to start the next dispatch cycle.
2344 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2345}
2346
2347void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
2348 const sp<Connection>& connection, bool notify) {
2349#if DEBUG_DISPATCH_CYCLE
2350 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002351 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002352#endif
2353
2354 // Clear the dispatch queues.
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002355 drainDispatchQueue(&connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002356 traceOutboundQueueLength(connection);
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002357 drainDispatchQueue(&connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002358 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002359
2360 // The connection appears to be unrecoverably broken.
2361 // Ignore already broken or zombie connections.
2362 if (connection->status == Connection::STATUS_NORMAL) {
2363 connection->status = Connection::STATUS_BROKEN;
2364
2365 if (notify) {
2366 // Notify other system components.
2367 onDispatchCycleBrokenLocked(currentTime, connection);
2368 }
2369 }
2370}
2371
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002372void InputDispatcher::drainDispatchQueue(Queue<DispatchEntry>* queue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002373 while (!queue->isEmpty()) {
2374 DispatchEntry* dispatchEntry = queue->dequeueAtHead();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002375 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002376 }
2377}
2378
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002379void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002380 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002381 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002382 }
2383 delete dispatchEntry;
2384}
2385
2386int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2387 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2388
2389 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002390 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002391
2392 ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
2393 if (connectionIndex < 0) {
2394 ALOGE("Received spurious receive callback for unknown input channel. "
2395 "fd=%d, events=0x%x", fd, events);
2396 return 0; // remove the callback
2397 }
2398
2399 bool notify;
2400 sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
2401 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2402 if (!(events & ALOOPER_EVENT_INPUT)) {
2403 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002404 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002405 return 1;
2406 }
2407
2408 nsecs_t currentTime = now();
2409 bool gotOne = false;
2410 status_t status;
2411 for (;;) {
2412 uint32_t seq;
2413 bool handled;
2414 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2415 if (status) {
2416 break;
2417 }
2418 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2419 gotOne = true;
2420 }
2421 if (gotOne) {
2422 d->runCommandsLockedInterruptible();
2423 if (status == WOULD_BLOCK) {
2424 return 1;
2425 }
2426 }
2427
2428 notify = status != DEAD_OBJECT || !connection->monitor;
2429 if (notify) {
2430 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002431 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002432 }
2433 } else {
2434 // Monitor channels are never explicitly unregistered.
2435 // We do it automatically when the remote endpoint is closed so don't warn
2436 // about them.
2437 notify = !connection->monitor;
2438 if (notify) {
2439 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002440 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002441 }
2442 }
2443
2444 // Unregister the channel.
2445 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2446 return 0; // remove the callback
2447 } // release lock
2448}
2449
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002450void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked (
Michael Wrightd02c5b62014-02-10 15:10:22 -08002451 const CancelationOptions& options) {
2452 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
2453 synthesizeCancelationEventsForConnectionLocked(
2454 mConnectionsByFd.valueAt(i), options);
2455 }
2456}
2457
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002458void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked (
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002459 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002460 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2461 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2462}
2463
2464void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2465 const CancelationOptions& options,
2466 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2467 for (const auto& it : monitorsByDisplay) {
2468 const std::vector<Monitor>& monitors = it.second;
2469 for (const Monitor& monitor : monitors) {
2470 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002471 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002472 }
2473}
2474
Michael Wrightd02c5b62014-02-10 15:10:22 -08002475void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2476 const sp<InputChannel>& channel, const CancelationOptions& options) {
2477 ssize_t index = getConnectionIndexLocked(channel);
2478 if (index >= 0) {
2479 synthesizeCancelationEventsForConnectionLocked(
2480 mConnectionsByFd.valueAt(index), options);
2481 }
2482}
2483
2484void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2485 const sp<Connection>& connection, const CancelationOptions& options) {
2486 if (connection->status == Connection::STATUS_BROKEN) {
2487 return;
2488 }
2489
2490 nsecs_t currentTime = now();
2491
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002492 std::vector<EventEntry*> cancelationEvents;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002493 connection->inputState.synthesizeCancelationEvents(currentTime,
2494 cancelationEvents, options);
2495
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002496 if (!cancelationEvents.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002497#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002498 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Michael Wrightd02c5b62014-02-10 15:10:22 -08002499 "with reality: %s, mode=%d.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002500 connection->getInputChannelName().c_str(), cancelationEvents.size(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002501 options.reason, options.mode);
2502#endif
2503 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002504 EventEntry* cancelationEventEntry = cancelationEvents[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002505 switch (cancelationEventEntry->type) {
2506 case EventEntry::TYPE_KEY:
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002507 logOutboundKeyDetails("cancel - ",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002508 static_cast<KeyEntry*>(cancelationEventEntry));
2509 break;
2510 case EventEntry::TYPE_MOTION:
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002511 logOutboundMotionDetails("cancel - ",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002512 static_cast<MotionEntry*>(cancelationEventEntry));
2513 break;
2514 }
2515
2516 InputTarget target;
chaviwfbe5d9c2018-12-26 12:23:37 -08002517 sp<InputWindowHandle> windowHandle = getWindowHandleLocked(
2518 connection->inputChannel->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07002519 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002520 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2521 target.xOffset = -windowInfo->frameLeft;
2522 target.yOffset = -windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08002523 target.globalScaleFactor = windowInfo->globalScaleFactor;
2524 target.windowXScale = windowInfo->windowXScale;
2525 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002526 } else {
2527 target.xOffset = 0;
2528 target.yOffset = 0;
Robert Carre07e1032018-11-26 12:55:53 -08002529 target.globalScaleFactor = 1.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002530 }
2531 target.inputChannel = connection->inputChannel;
2532 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2533
chaviw8c9cf542019-03-25 13:02:48 -07002534 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
Michael Wrightd02c5b62014-02-10 15:10:22 -08002535 &target, InputTarget::FLAG_DISPATCH_AS_IS);
2536
2537 cancelationEventEntry->release();
2538 }
2539
2540 startDispatchCycleLocked(currentTime, connection);
2541 }
2542}
2543
2544InputDispatcher::MotionEntry*
2545InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2546 ALOG_ASSERT(pointerIds.value != 0);
2547
2548 uint32_t splitPointerIndexMap[MAX_POINTERS];
2549 PointerProperties splitPointerProperties[MAX_POINTERS];
2550 PointerCoords splitPointerCoords[MAX_POINTERS];
2551
2552 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2553 uint32_t splitPointerCount = 0;
2554
2555 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2556 originalPointerIndex++) {
2557 const PointerProperties& pointerProperties =
2558 originalMotionEntry->pointerProperties[originalPointerIndex];
2559 uint32_t pointerId = uint32_t(pointerProperties.id);
2560 if (pointerIds.hasBit(pointerId)) {
2561 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2562 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2563 splitPointerCoords[splitPointerCount].copyFrom(
2564 originalMotionEntry->pointerCoords[originalPointerIndex]);
2565 splitPointerCount += 1;
2566 }
2567 }
2568
2569 if (splitPointerCount != pointerIds.count()) {
2570 // This is bad. We are missing some of the pointers that we expected to deliver.
2571 // Most likely this indicates that we received an ACTION_MOVE events that has
2572 // different pointer ids than we expected based on the previous ACTION_DOWN
2573 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2574 // in this way.
2575 ALOGW("Dropping split motion event because the pointer count is %d but "
2576 "we expected there to be %d pointers. This probably means we received "
2577 "a broken sequence of pointer ids from the input device.",
2578 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002579 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002580 }
2581
2582 int32_t action = originalMotionEntry->action;
2583 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2584 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2585 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2586 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2587 const PointerProperties& pointerProperties =
2588 originalMotionEntry->pointerProperties[originalPointerIndex];
2589 uint32_t pointerId = uint32_t(pointerProperties.id);
2590 if (pointerIds.hasBit(pointerId)) {
2591 if (pointerIds.count() == 1) {
2592 // The first/last pointer went down/up.
2593 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2594 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2595 } else {
2596 // A secondary pointer went down/up.
2597 uint32_t splitPointerIndex = 0;
2598 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2599 splitPointerIndex += 1;
2600 }
2601 action = maskedAction | (splitPointerIndex
2602 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2603 }
2604 } else {
2605 // An unrelated pointer changed.
2606 action = AMOTION_EVENT_ACTION_MOVE;
2607 }
2608 }
2609
Garfield Tan00f511d2019-06-12 16:55:40 -07002610 MotionEntry* splitMotionEntry =
2611 new MotionEntry(originalMotionEntry->sequenceNum, originalMotionEntry->eventTime,
2612 originalMotionEntry->deviceId, originalMotionEntry->source,
2613 originalMotionEntry->displayId, originalMotionEntry->policyFlags,
2614 action, originalMotionEntry->actionButton, originalMotionEntry->flags,
2615 originalMotionEntry->metaState, originalMotionEntry->buttonState,
2616 originalMotionEntry->classification, originalMotionEntry->edgeFlags,
2617 originalMotionEntry->xPrecision, originalMotionEntry->yPrecision,
2618 originalMotionEntry->xCursorPosition,
2619 originalMotionEntry->yCursorPosition, originalMotionEntry->downTime,
2620 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002621
2622 if (originalMotionEntry->injectionState) {
2623 splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2624 splitMotionEntry->injectionState->refCount += 1;
2625 }
2626
2627 return splitMotionEntry;
2628}
2629
2630void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2631#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002632 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002633#endif
2634
2635 bool needWake;
2636 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002637 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002638
Prabir Pradhan42611e02018-11-27 14:04:02 -08002639 ConfigurationChangedEntry* newEntry =
2640 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002641 needWake = enqueueInboundEventLocked(newEntry);
2642 } // release lock
2643
2644 if (needWake) {
2645 mLooper->wake();
2646 }
2647}
2648
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002649/**
2650 * If one of the meta shortcuts is detected, process them here:
2651 * Meta + Backspace -> generate BACK
2652 * Meta + Enter -> generate HOME
2653 * This will potentially overwrite keyCode and metaState.
2654 */
2655void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
2656 int32_t& keyCode, int32_t& metaState) {
2657 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2658 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2659 if (keyCode == AKEYCODE_DEL) {
2660 newKeyCode = AKEYCODE_BACK;
2661 } else if (keyCode == AKEYCODE_ENTER) {
2662 newKeyCode = AKEYCODE_HOME;
2663 }
2664 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002665 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002666 struct KeyReplacement replacement = {keyCode, deviceId};
2667 mReplacedKeys.add(replacement, newKeyCode);
2668 keyCode = newKeyCode;
2669 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2670 }
2671 } else if (action == AKEY_EVENT_ACTION_UP) {
2672 // In order to maintain a consistent stream of up and down events, check to see if the key
2673 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2674 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002675 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002676 struct KeyReplacement replacement = {keyCode, deviceId};
2677 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2678 if (index >= 0) {
2679 keyCode = mReplacedKeys.valueAt(index);
2680 mReplacedKeys.removeItemsAt(index);
2681 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2682 }
2683 }
2684}
2685
Michael Wrightd02c5b62014-02-10 15:10:22 -08002686void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2687#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002688 ALOGD("notifyKey - eventTime=%" PRId64
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002689 ", deviceId=%d, source=0x%x, displayId=%" PRId32 "policyFlags=0x%x, action=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +08002690 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002691 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002692 args->action, args->flags, args->keyCode, args->scanCode,
Arthur Hung82a4cad2018-11-15 12:10:30 +08002693 args->metaState, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002694#endif
2695 if (!validateKeyEvent(args->action)) {
2696 return;
2697 }
2698
2699 uint32_t policyFlags = args->policyFlags;
2700 int32_t flags = args->flags;
2701 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002702 // InputDispatcher tracks and generates key repeats on behalf of
2703 // whatever notifies it, so repeatCount should always be set to 0
2704 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002705 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2706 policyFlags |= POLICY_FLAG_VIRTUAL;
2707 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2708 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002709 if (policyFlags & POLICY_FLAG_FUNCTION) {
2710 metaState |= AMETA_FUNCTION_ON;
2711 }
2712
2713 policyFlags |= POLICY_FLAG_TRUSTED;
2714
Michael Wright78f24442014-08-06 15:55:28 -07002715 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002716 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002717
Michael Wrightd02c5b62014-02-10 15:10:22 -08002718 KeyEvent event;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002719 event.initialize(args->deviceId, args->source, args->displayId, args->action,
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002720 flags, keyCode, args->scanCode, metaState, repeatCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002721 args->downTime, args->eventTime);
2722
Michael Wright2b3c3302018-03-02 17:19:13 +00002723 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002724 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002725 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2726 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2727 std::to_string(t.duration().count()).c_str());
2728 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002729
Michael Wrightd02c5b62014-02-10 15:10:22 -08002730 bool needWake;
2731 { // acquire lock
2732 mLock.lock();
2733
2734 if (shouldSendKeyToInputFilterLocked(args)) {
2735 mLock.unlock();
2736
2737 policyFlags |= POLICY_FLAG_FILTERED;
2738 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2739 return; // event was consumed by the filter
2740 }
2741
2742 mLock.lock();
2743 }
2744
Prabir Pradhan42611e02018-11-27 14:04:02 -08002745 KeyEntry* newEntry = new KeyEntry(args->sequenceNum, args->eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002746 args->deviceId, args->source, args->displayId, policyFlags,
Michael Wright78f24442014-08-06 15:55:28 -07002747 args->action, flags, keyCode, args->scanCode,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002748 metaState, repeatCount, args->downTime);
2749
2750 needWake = enqueueInboundEventLocked(newEntry);
2751 mLock.unlock();
2752 } // release lock
2753
2754 if (needWake) {
2755 mLooper->wake();
2756 }
2757}
2758
2759bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2760 return mInputFilterEnabled;
2761}
2762
2763void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2764#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002765 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07002766 ", policyFlags=0x%x, "
2767 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
2768 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
2769 "mYCursorPosition=%f, downTime=%" PRId64,
2770 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2771 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
2772 args->edgeFlags, args->xPrecision, args->yPrecision, arg->xCursorPosition,
2773 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002774 for (uint32_t i = 0; i < args->pointerCount; i++) {
2775 ALOGD(" Pointer %d: id=%d, toolType=%d, "
2776 "x=%f, y=%f, pressure=%f, size=%f, "
2777 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2778 "orientation=%f",
2779 i, args->pointerProperties[i].id,
2780 args->pointerProperties[i].toolType,
2781 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2782 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2783 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2784 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2785 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2786 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2787 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2788 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2789 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2790 }
2791#endif
Michael Wright7b159c92015-05-14 14:48:03 +01002792 if (!validateMotionEvent(args->action, args->actionButton,
2793 args->pointerCount, args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002794 return;
2795 }
2796
2797 uint32_t policyFlags = args->policyFlags;
2798 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00002799
2800 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002801 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002802 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2803 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2804 std::to_string(t.duration().count()).c_str());
2805 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002806
2807 bool needWake;
2808 { // acquire lock
2809 mLock.lock();
2810
2811 if (shouldSendMotionToInputFilterLocked(args)) {
2812 mLock.unlock();
2813
2814 MotionEvent event;
Garfield Tan00f511d2019-06-12 16:55:40 -07002815 event.initialize(args->deviceId, args->source, args->displayId, args->action,
2816 args->actionButton, args->flags, args->edgeFlags, args->metaState,
2817 args->buttonState, args->classification, 0, 0, args->xPrecision,
2818 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2819 args->downTime, args->eventTime, args->pointerCount,
2820 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002821
2822 policyFlags |= POLICY_FLAG_FILTERED;
2823 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2824 return; // event was consumed by the filter
2825 }
2826
2827 mLock.lock();
2828 }
2829
2830 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002831 MotionEntry* newEntry =
2832 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2833 args->displayId, policyFlags, args->action, args->actionButton,
2834 args->flags, args->metaState, args->buttonState,
2835 args->classification, args->edgeFlags, args->xPrecision,
2836 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2837 args->downTime, args->pointerCount, args->pointerProperties,
2838 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002839
2840 needWake = enqueueInboundEventLocked(newEntry);
2841 mLock.unlock();
2842 } // release lock
2843
2844 if (needWake) {
2845 mLooper->wake();
2846 }
2847}
2848
2849bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08002850 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002851}
2852
2853void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2854#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002855 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
2856 "switchMask=0x%08x",
2857 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002858#endif
2859
2860 uint32_t policyFlags = args->policyFlags;
2861 policyFlags |= POLICY_FLAG_TRUSTED;
2862 mPolicy->notifySwitch(args->eventTime,
2863 args->switchValues, args->switchMask, policyFlags);
2864}
2865
2866void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
2867#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002868 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002869 args->eventTime, args->deviceId);
2870#endif
2871
2872 bool needWake;
2873 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002874 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002875
Prabir Pradhan42611e02018-11-27 14:04:02 -08002876 DeviceResetEntry* newEntry =
2877 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002878 needWake = enqueueInboundEventLocked(newEntry);
2879 } // release lock
2880
2881 if (needWake) {
2882 mLooper->wake();
2883 }
2884}
2885
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002886int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002887 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
2888 uint32_t policyFlags) {
2889#if DEBUG_INBOUND_EVENT_DETAILS
2890 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002891 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2892 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002893#endif
2894
2895 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2896
2897 policyFlags |= POLICY_FLAG_INJECTED;
2898 if (hasInjectionPermission(injectorPid, injectorUid)) {
2899 policyFlags |= POLICY_FLAG_TRUSTED;
2900 }
2901
2902 EventEntry* firstInjectedEntry;
2903 EventEntry* lastInjectedEntry;
2904 switch (event->getType()) {
2905 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002906 KeyEvent keyEvent;
2907 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
2908 int32_t action = keyEvent.getAction();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002909 if (! validateKeyEvent(action)) {
2910 return INPUT_EVENT_INJECTION_FAILED;
2911 }
2912
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002913 int32_t flags = keyEvent.getFlags();
2914 int32_t keyCode = keyEvent.getKeyCode();
2915 int32_t metaState = keyEvent.getMetaState();
2916 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
2917 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002918 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002919 action, flags, keyCode, keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002920 keyEvent.getDownTime(), keyEvent.getEventTime());
2921
Michael Wrightd02c5b62014-02-10 15:10:22 -08002922 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2923 policyFlags |= POLICY_FLAG_VIRTUAL;
2924 }
2925
2926 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wright2b3c3302018-03-02 17:19:13 +00002927 android::base::Timer t;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002928 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002929 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2930 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2931 std::to_string(t.duration().count()).c_str());
2932 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002933 }
2934
Michael Wrightd02c5b62014-02-10 15:10:22 -08002935 mLock.lock();
Prabir Pradhan42611e02018-11-27 14:04:02 -08002936 firstInjectedEntry = new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002937 keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002938 policyFlags, action, flags,
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002939 keyEvent.getKeyCode(), keyEvent.getScanCode(), keyEvent.getMetaState(),
2940 keyEvent.getRepeatCount(), keyEvent.getDownTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002941 lastInjectedEntry = firstInjectedEntry;
2942 break;
2943 }
2944
2945 case AINPUT_EVENT_TYPE_MOTION: {
2946 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002947 int32_t action = motionEvent->getAction();
2948 size_t pointerCount = motionEvent->getPointerCount();
2949 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
Michael Wright7b159c92015-05-14 14:48:03 +01002950 int32_t actionButton = motionEvent->getActionButton();
Charles Chen3611f1f2019-01-29 17:26:18 +08002951 int32_t displayId = motionEvent->getDisplayId();
Michael Wright7b159c92015-05-14 14:48:03 +01002952 if (! validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002953 return INPUT_EVENT_INJECTION_FAILED;
2954 }
2955
2956 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2957 nsecs_t eventTime = motionEvent->getEventTime();
Michael Wright2b3c3302018-03-02 17:19:13 +00002958 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002959 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002960 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2961 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2962 std::to_string(t.duration().count()).c_str());
2963 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002964 }
2965
2966 mLock.lock();
2967 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2968 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Garfield Tan00f511d2019-06-12 16:55:40 -07002969 firstInjectedEntry =
2970 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
2971 motionEvent->getDeviceId(), motionEvent->getSource(),
2972 motionEvent->getDisplayId(), policyFlags, action, actionButton,
2973 motionEvent->getFlags(), motionEvent->getMetaState(),
2974 motionEvent->getButtonState(), motionEvent->getClassification(),
2975 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
2976 motionEvent->getYPrecision(), motionEvent->getRawXCursorPosition(),
2977 motionEvent->getRawYCursorPosition(), motionEvent->getDownTime(),
2978 uint32_t(pointerCount), pointerProperties, samplePointerCoords,
2979 motionEvent->getXOffset(), motionEvent->getYOffset());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002980 lastInjectedEntry = firstInjectedEntry;
2981 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2982 sampleEventTimes += 1;
2983 samplePointerCoords += pointerCount;
Garfield Tan00f511d2019-06-12 16:55:40 -07002984 MotionEntry* nextInjectedEntry =
2985 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
2986 motionEvent->getDeviceId(), motionEvent->getSource(),
2987 motionEvent->getDisplayId(), policyFlags, action, actionButton,
2988 motionEvent->getFlags(), motionEvent->getMetaState(),
2989 motionEvent->getButtonState(), motionEvent->getClassification(),
2990 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
2991 motionEvent->getYPrecision(),
2992 motionEvent->getRawXCursorPosition(),
2993 motionEvent->getRawYCursorPosition(),
2994 motionEvent->getDownTime(), uint32_t(pointerCount),
2995 pointerProperties, samplePointerCoords,
2996 motionEvent->getXOffset(), motionEvent->getYOffset());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002997 lastInjectedEntry->next = nextInjectedEntry;
2998 lastInjectedEntry = nextInjectedEntry;
2999 }
3000 break;
3001 }
3002
3003 default:
3004 ALOGW("Cannot inject event of type %d", event->getType());
3005 return INPUT_EVENT_INJECTION_FAILED;
3006 }
3007
3008 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3009 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3010 injectionState->injectionIsAsync = true;
3011 }
3012
3013 injectionState->refCount += 1;
3014 lastInjectedEntry->injectionState = injectionState;
3015
3016 bool needWake = false;
Yi Kong9b14ac62018-07-17 13:48:38 -07003017 for (EventEntry* entry = firstInjectedEntry; entry != nullptr; ) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003018 EventEntry* nextEntry = entry->next;
3019 needWake |= enqueueInboundEventLocked(entry);
3020 entry = nextEntry;
3021 }
3022
3023 mLock.unlock();
3024
3025 if (needWake) {
3026 mLooper->wake();
3027 }
3028
3029 int32_t injectionResult;
3030 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003031 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003032
3033 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3034 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3035 } else {
3036 for (;;) {
3037 injectionResult = injectionState->injectionResult;
3038 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3039 break;
3040 }
3041
3042 nsecs_t remainingTimeout = endTime - now();
3043 if (remainingTimeout <= 0) {
3044#if DEBUG_INJECTION
3045 ALOGD("injectInputEvent - Timed out waiting for injection result "
3046 "to become available.");
3047#endif
3048 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3049 break;
3050 }
3051
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003052 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003053 }
3054
3055 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
3056 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
3057 while (injectionState->pendingForegroundDispatches != 0) {
3058#if DEBUG_INJECTION
3059 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
3060 injectionState->pendingForegroundDispatches);
3061#endif
3062 nsecs_t remainingTimeout = endTime - now();
3063 if (remainingTimeout <= 0) {
3064#if DEBUG_INJECTION
3065 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3066 "dispatches to finish.");
3067#endif
3068 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3069 break;
3070 }
3071
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003072 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003073 }
3074 }
3075 }
3076
3077 injectionState->release();
3078 } // release lock
3079
3080#if DEBUG_INJECTION
3081 ALOGD("injectInputEvent - Finished with result %d. "
3082 "injectorPid=%d, injectorUid=%d",
3083 injectionResult, injectorPid, injectorUid);
3084#endif
3085
3086 return injectionResult;
3087}
3088
3089bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
3090 return injectorUid == 0
3091 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
3092}
3093
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003094void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003095 InjectionState* injectionState = entry->injectionState;
3096 if (injectionState) {
3097#if DEBUG_INJECTION
3098 ALOGD("Setting input event injection result to %d. "
3099 "injectorPid=%d, injectorUid=%d",
3100 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
3101#endif
3102
3103 if (injectionState->injectionIsAsync
3104 && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
3105 // Log the outcome since the injector did not wait for the injection result.
3106 switch (injectionResult) {
3107 case INPUT_EVENT_INJECTION_SUCCEEDED:
3108 ALOGV("Asynchronous input event injection succeeded.");
3109 break;
3110 case INPUT_EVENT_INJECTION_FAILED:
3111 ALOGW("Asynchronous input event injection failed.");
3112 break;
3113 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3114 ALOGW("Asynchronous input event injection permission denied.");
3115 break;
3116 case INPUT_EVENT_INJECTION_TIMED_OUT:
3117 ALOGW("Asynchronous input event injection timed out.");
3118 break;
3119 }
3120 }
3121
3122 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003123 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003124 }
3125}
3126
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003127void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003128 InjectionState* injectionState = entry->injectionState;
3129 if (injectionState) {
3130 injectionState->pendingForegroundDispatches += 1;
3131 }
3132}
3133
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003134void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003135 InjectionState* injectionState = entry->injectionState;
3136 if (injectionState) {
3137 injectionState->pendingForegroundDispatches -= 1;
3138
3139 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003140 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003141 }
3142 }
3143}
3144
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003145std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3146 int32_t displayId) const {
3147 std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>::const_iterator it =
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003148 mWindowHandlesByDisplay.find(displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003149 if(it != mWindowHandlesByDisplay.end()) {
3150 return it->second;
3151 }
3152
3153 // Return an empty one if nothing found.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003154 return std::vector<sp<InputWindowHandle>>();
Arthur Hungb92218b2018-08-14 12:00:21 +08003155}
3156
Michael Wrightd02c5b62014-02-10 15:10:22 -08003157sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003158 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003159 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003160 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3161 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003162 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003163 return windowHandle;
3164 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003165 }
3166 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003167 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003168}
3169
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003170bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003171 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003172 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3173 for (const sp<InputWindowHandle>& handle : windowHandles) {
3174 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003175 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003176 ALOGE("Found window %s in display %" PRId32
3177 ", but it should belong to display %" PRId32,
3178 windowHandle->getName().c_str(), it.first,
3179 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003180 }
3181 return true;
3182 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003183 }
3184 }
3185 return false;
3186}
3187
Robert Carr5c8a0262018-10-03 16:30:44 -07003188sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3189 size_t count = mInputChannelsByToken.count(token);
3190 if (count == 0) {
3191 return nullptr;
3192 }
3193 return mInputChannelsByToken.at(token);
3194}
3195
Arthur Hungb92218b2018-08-14 12:00:21 +08003196/**
3197 * Called from InputManagerService, update window handle list by displayId that can receive input.
3198 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3199 * If set an empty list, remove all handles from the specific display.
3200 * For focused handle, check if need to change and send a cancel event to previous one.
3201 * For removed handle, check if need to send a cancel event if already in touch.
3202 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003203void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
chaviw291d88a2019-02-14 10:33:58 -08003204 int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003205#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003206 ALOGD("setInputWindows displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003207#endif
3208 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003209 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003210
Arthur Hungb92218b2018-08-14 12:00:21 +08003211 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003212 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3213 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003214
Tiger Huang721e26f2018-07-24 22:26:19 +08003215 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003216 bool foundHoveredWindow = false;
Arthur Hungb92218b2018-08-14 12:00:21 +08003217
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003218 if (inputWindowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003219 // Remove all handles on a display if there are no windows left.
3220 mWindowHandlesByDisplay.erase(displayId);
3221 } else {
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003222 // Since we compare the pointer of input window handles across window updates, we need
3223 // to make sure the handle object for the same window stays unchanged across updates.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003224 const std::vector<sp<InputWindowHandle>>& oldHandles =
3225 mWindowHandlesByDisplay[displayId];
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003226 std::unordered_map<sp<IBinder>, sp<InputWindowHandle>, IBinderHash> oldHandlesByTokens;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003227 for (const sp<InputWindowHandle>& handle : oldHandles) {
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003228 oldHandlesByTokens[handle->getToken()] = handle;
3229 }
3230
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003231 std::vector<sp<InputWindowHandle>> newHandles;
3232 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
Siarhei Vishniakou3a179dc2019-01-30 09:50:04 -08003233 if (!handle->updateInfo()) {
3234 // handle no longer valid
3235 continue;
3236 }
3237 const InputWindowInfo* info = handle->getInfo();
3238
3239 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3240 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3241 const bool noInputChannel =
3242 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3243 const bool canReceiveInput =
3244 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3245 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3246 if (canReceiveInput && !noInputChannel) {
3247 ALOGE("Window handle %s has no registered input channel",
3248 handle->getName().c_str());
3249 }
Arthur Hungb92218b2018-08-14 12:00:21 +08003250 continue;
3251 }
3252
Siarhei Vishniakou3a179dc2019-01-30 09:50:04 -08003253 if (info->displayId != displayId) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003254 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
Siarhei Vishniakou3a179dc2019-01-30 09:50:04 -08003255 handle->getName().c_str(), displayId, info->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003256 continue;
3257 }
3258
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003259 if (oldHandlesByTokens.find(handle->getToken()) != oldHandlesByTokens.end()) {
3260 const sp<InputWindowHandle> oldHandle =
3261 oldHandlesByTokens.at(handle->getToken());
3262 oldHandle->updateFrom(handle);
3263 newHandles.push_back(oldHandle);
3264 } else {
3265 newHandles.push_back(handle);
3266 }
3267 }
3268
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003269 for (const sp<InputWindowHandle>& windowHandle : newHandles) {
Arthur Hung7ab76b12019-01-09 19:17:20 +08003270 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3271 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus
3272 && windowHandle->getInfo()->visible) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003273 newFocusedWindowHandle = windowHandle;
3274 }
3275 if (windowHandle == mLastHoverWindowHandle) {
3276 foundHoveredWindow = true;
3277 }
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003278 }
Arthur Hungb92218b2018-08-14 12:00:21 +08003279
3280 // Insert or replace
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003281 mWindowHandlesByDisplay[displayId] = newHandles;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003282 }
3283
3284 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003285 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003286 }
3287
Tiger Huang721e26f2018-07-24 22:26:19 +08003288 sp<InputWindowHandle> oldFocusedWindowHandle =
3289 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3290
3291 if (oldFocusedWindowHandle != newFocusedWindowHandle) {
3292 if (oldFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003293#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003294 ALOGD("Focus left window: %s in display %" PRId32,
3295 oldFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003296#endif
Robert Carr5c8a0262018-10-03 16:30:44 -07003297 sp<InputChannel> focusedInputChannel = getInputChannelLocked(
3298 oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003299 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003300 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3301 "focus left window");
3302 synthesizeCancelationEventsForInputChannelLocked(
3303 focusedInputChannel, options);
3304 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003305 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003306 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003307 if (newFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003308#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003309 ALOGD("Focus entered window: %s in display %" PRId32,
3310 newFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003311#endif
Tiger Huang721e26f2018-07-24 22:26:19 +08003312 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003313 }
Robert Carrf759f162018-11-13 12:57:11 -08003314
3315 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003316 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003317 }
3318
Michael Wrightd02c5b62014-02-10 15:10:22 -08003319 }
3320
Arthur Hungb92218b2018-08-14 12:00:21 +08003321 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3322 if (stateIndex >= 0) {
3323 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Ivan Lozano96f12992017-11-09 14:45:38 -08003324 for (size_t i = 0; i < state.windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003325 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003326 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003328 ALOGD("Touched window was removed: %s in display %" PRId32,
3329 touchedWindow.windowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003330#endif
Jeff Brownf086ddb2014-02-11 14:28:48 -08003331 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003332 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003333 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003334 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3335 "touched window was removed");
3336 synthesizeCancelationEventsForInputChannelLocked(
3337 touchedInputChannel, options);
3338 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003339 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003340 } else {
3341 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003342 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003343 }
3344 }
3345
3346 // Release information for windows that are no longer present.
3347 // This ensures that unused input channels are released promptly.
3348 // Otherwise, they might stick around until the window handle is destroyed
3349 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003350 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003351 if (!hasWindowHandleLocked(oldWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003352#if DEBUG_FOCUS
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003353 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003354#endif
Arthur Hung3b413f22018-10-26 18:05:34 +08003355 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003356 }
3357 }
3358 } // release lock
3359
3360 // Wake up poll loop since it may need to make new input dispatching choices.
3361 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003362
3363 if (setInputWindowsListener) {
3364 setInputWindowsListener->onSetInputWindowsFinished();
3365 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003366}
3367
3368void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003369 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003370#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003371 ALOGD("setFocusedApplication displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003372#endif
3373 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003374 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003375
Tiger Huang721e26f2018-07-24 22:26:19 +08003376 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3377 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003378 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003379 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3380 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003381 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003382 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003383 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003384 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003385 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003386 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003387 oldFocusedApplicationHandle.clear();
3388 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003389 }
3390
3391#if DEBUG_FOCUS
3392 //logDispatchStateLocked();
3393#endif
3394 } // release lock
3395
3396 // Wake up poll loop since it may need to make new input dispatching choices.
3397 mLooper->wake();
3398}
3399
Tiger Huang721e26f2018-07-24 22:26:19 +08003400/**
3401 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3402 * the display not specified.
3403 *
3404 * We track any unreleased events for each window. If a window loses the ability to receive the
3405 * released event, we will send a cancel event to it. So when the focused display is changed, we
3406 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3407 * display. The display-specified events won't be affected.
3408 */
3409void InputDispatcher::setFocusedDisplay(int32_t displayId) {
3410#if DEBUG_FOCUS
3411 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3412#endif
3413 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003414 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003415
3416 if (mFocusedDisplayId != displayId) {
3417 sp<InputWindowHandle> oldFocusedWindowHandle =
3418 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3419 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003420 sp<InputChannel> inputChannel =
3421 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003422 if (inputChannel != nullptr) {
3423 CancelationOptions options(
Michael Wright3dd60e22019-03-27 22:06:44 +00003424 CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Tiger Huang721e26f2018-07-24 22:26:19 +08003425 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003426 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003427 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3428 }
3429 }
3430 mFocusedDisplayId = displayId;
3431
3432 // Sanity check
3433 sp<InputWindowHandle> newFocusedWindowHandle =
3434 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003435 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003436
Tiger Huang721e26f2018-07-24 22:26:19 +08003437 if (newFocusedWindowHandle == nullptr) {
3438 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3439 if (!mFocusedWindowHandlesByDisplay.empty()) {
3440 ALOGE("But another display has a focused window:");
3441 for (auto& it : mFocusedWindowHandlesByDisplay) {
3442 const int32_t displayId = it.first;
3443 const sp<InputWindowHandle>& windowHandle = it.second;
3444 ALOGE("Display #%" PRId32 " has focused window: '%s'\n",
3445 displayId, windowHandle->getName().c_str());
3446 }
3447 }
3448 }
3449 }
3450
3451#if DEBUG_FOCUS
3452 logDispatchStateLocked();
3453#endif
3454 } // release lock
3455
3456 // Wake up poll loop since it may need to make new input dispatching choices.
3457 mLooper->wake();
3458}
3459
Michael Wrightd02c5b62014-02-10 15:10:22 -08003460void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
3461#if DEBUG_FOCUS
3462 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3463#endif
3464
3465 bool changed;
3466 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003467 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003468
3469 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3470 if (mDispatchFrozen && !frozen) {
3471 resetANRTimeoutsLocked();
3472 }
3473
3474 if (mDispatchEnabled && !enabled) {
3475 resetAndDropEverythingLocked("dispatcher is being disabled");
3476 }
3477
3478 mDispatchEnabled = enabled;
3479 mDispatchFrozen = frozen;
3480 changed = true;
3481 } else {
3482 changed = false;
3483 }
3484
3485#if DEBUG_FOCUS
Tiger Huang721e26f2018-07-24 22:26:19 +08003486 logDispatchStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003487#endif
3488 } // release lock
3489
3490 if (changed) {
3491 // Wake up poll loop since it may need to make new input dispatching choices.
3492 mLooper->wake();
3493 }
3494}
3495
3496void InputDispatcher::setInputFilterEnabled(bool enabled) {
3497#if DEBUG_FOCUS
3498 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3499#endif
3500
3501 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003502 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003503
3504 if (mInputFilterEnabled == enabled) {
3505 return;
3506 }
3507
3508 mInputFilterEnabled = enabled;
3509 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3510 } // release lock
3511
3512 // Wake up poll loop since there might be work to do to drop everything.
3513 mLooper->wake();
3514}
3515
chaviwfbe5d9c2018-12-26 12:23:37 -08003516bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3517 if (fromToken == toToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003518#if DEBUG_FOCUS
chaviwfbe5d9c2018-12-26 12:23:37 -08003519 ALOGD("Trivial transfer to same window.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003520#endif
chaviwfbe5d9c2018-12-26 12:23:37 -08003521 return true;
3522 }
3523
Michael Wrightd02c5b62014-02-10 15:10:22 -08003524 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003525 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003526
chaviwfbe5d9c2018-12-26 12:23:37 -08003527 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3528 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003529 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003530 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003531 return false;
3532 }
chaviw4f2dd402018-12-26 15:30:27 -08003533#if DEBUG_FOCUS
3534 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3535 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3536#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003537 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
3538#if DEBUG_FOCUS
3539 ALOGD("Cannot transfer focus because windows are on different displays.");
3540#endif
3541 return false;
3542 }
3543
3544 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003545 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3546 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3547 for (size_t i = 0; i < state.windows.size(); i++) {
3548 const TouchedWindow& touchedWindow = state.windows[i];
3549 if (touchedWindow.windowHandle == fromWindowHandle) {
3550 int32_t oldTargetFlags = touchedWindow.targetFlags;
3551 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003552
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003553 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003554
Jeff Brownf086ddb2014-02-11 14:28:48 -08003555 int32_t newTargetFlags = oldTargetFlags
3556 & (InputTarget::FLAG_FOREGROUND
3557 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
3558 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003559
Jeff Brownf086ddb2014-02-11 14:28:48 -08003560 found = true;
3561 goto Found;
3562 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003563 }
3564 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003565Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003566
3567 if (! found) {
3568#if DEBUG_FOCUS
3569 ALOGD("Focus transfer failed because from window did not have focus.");
3570#endif
3571 return false;
3572 }
3573
chaviwfbe5d9c2018-12-26 12:23:37 -08003574
3575 sp<InputChannel> fromChannel = getInputChannelLocked(fromToken);
3576 sp<InputChannel> toChannel = getInputChannelLocked(toToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003577 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
3578 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
3579 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
3580 sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
3581 sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
3582
3583 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
3584 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3585 "transferring touch focus from this window to another window");
3586 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
3587 }
3588
3589#if DEBUG_FOCUS
3590 logDispatchStateLocked();
3591#endif
3592 } // release lock
3593
3594 // Wake up poll loop since it may need to make new input dispatching choices.
3595 mLooper->wake();
3596 return true;
3597}
3598
3599void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
3600#if DEBUG_FOCUS
3601 ALOGD("Resetting and dropping all events (%s).", reason);
3602#endif
3603
3604 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3605 synthesizeCancelationEventsForAllConnectionsLocked(options);
3606
3607 resetKeyRepeatLocked();
3608 releasePendingEventLocked();
3609 drainInboundQueueLocked();
3610 resetANRTimeoutsLocked();
3611
Jeff Brownf086ddb2014-02-11 14:28:48 -08003612 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003613 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003614 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003615}
3616
3617void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003618 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003619 dumpDispatchStateLocked(dump);
3620
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003621 std::istringstream stream(dump);
3622 std::string line;
3623
3624 while (std::getline(stream, line, '\n')) {
3625 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003626 }
3627}
3628
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003629void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003630 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3631 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3632 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003633 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003634
Tiger Huang721e26f2018-07-24 22:26:19 +08003635 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3636 dump += StringPrintf(INDENT "FocusedApplications:\n");
3637 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3638 const int32_t displayId = it.first;
3639 const sp<InputApplicationHandle>& applicationHandle = it.second;
3640 dump += StringPrintf(
3641 INDENT2 "displayId=%" PRId32 ", name='%s', dispatchingTimeout=%0.3fms\n",
3642 displayId,
3643 applicationHandle->getName().c_str(),
3644 applicationHandle->getDispatchingTimeout(
3645 DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
3646 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003647 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003648 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003649 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003650
3651 if (!mFocusedWindowHandlesByDisplay.empty()) {
3652 dump += StringPrintf(INDENT "FocusedWindows:\n");
3653 for (auto& it : mFocusedWindowHandlesByDisplay) {
3654 const int32_t displayId = it.first;
3655 const sp<InputWindowHandle>& windowHandle = it.second;
3656 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n",
3657 displayId, windowHandle->getName().c_str());
3658 }
3659 } else {
3660 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3661 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003662
Jeff Brownf086ddb2014-02-11 14:28:48 -08003663 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003664 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003665 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3666 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003667 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Jeff Brownf086ddb2014-02-11 14:28:48 -08003668 state.displayId, toString(state.down), toString(state.split),
3669 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003670 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003671 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003672 for (size_t i = 0; i < state.windows.size(); i++) {
3673 const TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003674 dump += StringPrintf(INDENT4 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3675 i, touchedWindow.windowHandle->getName().c_str(),
Jeff Brownf086ddb2014-02-11 14:28:48 -08003676 touchedWindow.pointerIds.value,
3677 touchedWindow.targetFlags);
3678 }
3679 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003680 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003681 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003682 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003683 dump += INDENT3 "Portal windows:\n";
3684 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003685 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003686 dump += StringPrintf(INDENT4 "%zu: name='%s'\n",
3687 i, portalWindowHandle->getName().c_str());
3688 }
3689 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003690 }
3691 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003692 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003693 }
3694
Arthur Hungb92218b2018-08-14 12:00:21 +08003695 if (!mWindowHandlesByDisplay.empty()) {
3696 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003697 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003698 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003699 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003700 dump += INDENT2 "Windows:\n";
3701 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003702 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003703 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003704
Arthur Hungb92218b2018-08-14 12:00:21 +08003705 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003706 "portalToDisplayId=%d, paused=%s, hasFocus=%s, hasWallpaper=%s, "
Arthur Hungb92218b2018-08-14 12:00:21 +08003707 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
Riddle Hsu39d4aa52018-11-30 20:46:53 +08003708 "frame=[%d,%d][%d,%d], globalScale=%f, windowScale=(%f,%f), "
Arthur Hungb92218b2018-08-14 12:00:21 +08003709 "touchableRegion=",
3710 i, windowInfo->name.c_str(), windowInfo->displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003711 windowInfo->portalToDisplayId,
Arthur Hungb92218b2018-08-14 12:00:21 +08003712 toString(windowInfo->paused),
3713 toString(windowInfo->hasFocus),
3714 toString(windowInfo->hasWallpaper),
3715 toString(windowInfo->visible),
3716 toString(windowInfo->canReceiveKeys),
3717 windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
3718 windowInfo->layer,
3719 windowInfo->frameLeft, windowInfo->frameTop,
3720 windowInfo->frameRight, windowInfo->frameBottom,
Robert Carre07e1032018-11-26 12:55:53 -08003721 windowInfo->globalScaleFactor,
3722 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003723 dumpRegion(dump, windowInfo->touchableRegion);
3724 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3725 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
3726 windowInfo->ownerPid, windowInfo->ownerUid,
3727 windowInfo->dispatchingTimeout / 1000000.0);
3728 }
3729 } else {
3730 dump += INDENT2 "Windows: <none>\n";
3731 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003732 }
3733 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003734 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003735 }
3736
Michael Wright3dd60e22019-03-27 22:06:44 +00003737 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
3738 for (auto& it : mGlobalMonitorsByDisplay) {
3739 const std::vector<Monitor>& monitors = it.second;
3740 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3741 dumpMonitors(dump, monitors);
3742 }
3743 for (auto& it : mGestureMonitorsByDisplay) {
3744 const std::vector<Monitor>& monitors = it.second;
3745 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
3746 dumpMonitors(dump, monitors);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003747 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003748 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00003749 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003750 }
3751
3752 nsecs_t currentTime = now();
3753
3754 // Dump recently dispatched or dropped events from oldest to newest.
3755 if (!mRecentQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003756 dump += StringPrintf(INDENT "RecentQueue: length=%u\n", mRecentQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003757 for (EventEntry* entry = mRecentQueue.head; entry; entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003758 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003759 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003760 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003761 (currentTime - entry->eventTime) * 0.000001f);
3762 }
3763 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003764 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003765 }
3766
3767 // Dump event currently being dispatched.
3768 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003769 dump += INDENT "PendingEvent:\n";
3770 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003771 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003772 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003773 (currentTime - mPendingEvent->eventTime) * 0.000001f);
3774 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003775 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003776 }
3777
3778 // Dump inbound events from oldest to newest.
3779 if (!mInboundQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003780 dump += StringPrintf(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003781 for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003782 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003783 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003784 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003785 (currentTime - entry->eventTime) * 0.000001f);
3786 }
3787 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003788 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003789 }
3790
Michael Wright78f24442014-08-06 15:55:28 -07003791 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003792 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07003793 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
3794 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
3795 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003796 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n",
Michael Wright78f24442014-08-06 15:55:28 -07003797 i, replacement.keyCode, replacement.deviceId, newKeyCode);
3798 }
3799 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003800 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07003801 }
3802
Michael Wrightd02c5b62014-02-10 15:10:22 -08003803 if (!mConnectionsByFd.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003804 dump += INDENT "Connections:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003805 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
3806 const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003807 dump += StringPrintf(INDENT2 "%zu: channelName='%s', windowName='%s', "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003808 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08003809 i, connection->getInputChannelName().c_str(),
3810 connection->getWindowName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08003811 connection->getStatusLabel(), toString(connection->monitor),
3812 toString(connection->inputPublisherBlocked));
3813
3814 if (!connection->outboundQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003815 dump += StringPrintf(INDENT3 "OutboundQueue: length=%u\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003816 connection->outboundQueue.count());
3817 for (DispatchEntry* entry = connection->outboundQueue.head; entry;
3818 entry = entry->next) {
3819 dump.append(INDENT4);
3820 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003821 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003822 entry->targetFlags, entry->resolvedAction,
3823 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
3824 }
3825 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003826 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003827 }
3828
3829 if (!connection->waitQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003830 dump += StringPrintf(INDENT3 "WaitQueue: length=%u\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003831 connection->waitQueue.count());
3832 for (DispatchEntry* entry = connection->waitQueue.head; entry;
3833 entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003834 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003835 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003836 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003837 "age=%0.1fms, wait=%0.1fms\n",
3838 entry->targetFlags, entry->resolvedAction,
3839 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
3840 (currentTime - entry->deliveryTime) * 0.000001f);
3841 }
3842 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003843 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003844 }
3845 }
3846 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003847 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848 }
3849
3850 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003851 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003852 (mAppSwitchDueTime - now()) / 1000000.0);
3853 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003854 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003855 }
3856
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003857 dump += INDENT "Configuration:\n";
3858 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003859 mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003860 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003861 mConfig.keyRepeatTimeout * 0.000001f);
3862}
3863
Michael Wright3dd60e22019-03-27 22:06:44 +00003864void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
3865 const size_t numMonitors = monitors.size();
3866 for (size_t i = 0; i < numMonitors; i++) {
3867 const Monitor& monitor = monitors[i];
3868 const sp<InputChannel>& channel = monitor.inputChannel;
3869 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
3870 dump += "\n";
3871 }
3872}
3873
3874status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3875 int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003876#if DEBUG_REGISTRATION
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003877 ALOGD("channel '%s' ~ registerInputChannel - displayId=%" PRId32,
3878 inputChannel->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003879#endif
3880
3881 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003882 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003883
3884 if (getConnectionIndexLocked(inputChannel) >= 0) {
3885 ALOGW("Attempted to register already registered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003886 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003887 return BAD_VALUE;
3888 }
3889
Michael Wright3dd60e22019-03-27 22:06:44 +00003890 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003891
3892 int fd = inputChannel->getFd();
3893 mConnectionsByFd.add(fd, connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07003894 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003895
Michael Wrightd02c5b62014-02-10 15:10:22 -08003896 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3897 } // release lock
3898
3899 // Wake the looper because some connections have changed.
3900 mLooper->wake();
3901 return OK;
3902}
3903
Michael Wright3dd60e22019-03-27 22:06:44 +00003904status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
3905 int32_t displayId, bool isGestureMonitor) {
3906 { // acquire lock
3907 std::scoped_lock _l(mLock);
3908
3909 if (displayId < 0) {
3910 ALOGW("Attempted to register input monitor without a specified display.");
3911 return BAD_VALUE;
3912 }
3913
3914 if (inputChannel->getToken() == nullptr) {
3915 ALOGW("Attempted to register input monitor without an identifying token.");
3916 return BAD_VALUE;
3917 }
3918
3919 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
3920
3921 const int fd = inputChannel->getFd();
3922 mConnectionsByFd.add(fd, connection);
3923 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
3924
3925 auto& monitorsByDisplay = isGestureMonitor
3926 ? mGestureMonitorsByDisplay
3927 : mGlobalMonitorsByDisplay;
3928 monitorsByDisplay[displayId].emplace_back(inputChannel);
3929
3930 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3931
3932 }
3933 // Wake the looper because some connections have changed.
3934 mLooper->wake();
3935 return OK;
3936}
3937
Michael Wrightd02c5b62014-02-10 15:10:22 -08003938status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
3939#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003940 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003941#endif
3942
3943 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003944 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003945
3946 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3947 if (status) {
3948 return status;
3949 }
3950 } // release lock
3951
3952 // Wake the poll loop because removing the connection may have changed the current
3953 // synchronization state.
3954 mLooper->wake();
3955 return OK;
3956}
3957
3958status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
3959 bool notify) {
3960 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
3961 if (connectionIndex < 0) {
3962 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003963 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003964 return BAD_VALUE;
3965 }
3966
3967 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
3968 mConnectionsByFd.removeItemsAt(connectionIndex);
3969
Robert Carr5c8a0262018-10-03 16:30:44 -07003970 mInputChannelsByToken.erase(inputChannel->getToken());
3971
Michael Wrightd02c5b62014-02-10 15:10:22 -08003972 if (connection->monitor) {
3973 removeMonitorChannelLocked(inputChannel);
3974 }
3975
3976 mLooper->removeFd(inputChannel->getFd());
3977
3978 nsecs_t currentTime = now();
3979 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
3980
3981 connection->status = Connection::STATUS_ZOMBIE;
3982 return OK;
3983}
3984
3985void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003986 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
3987 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
3988}
3989
3990void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel,
3991 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3992 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end(); ) {
3993 std::vector<Monitor>& monitors = it->second;
3994 const size_t numMonitors = monitors.size();
3995 for (size_t i = 0; i < numMonitors; i++) {
3996 if (monitors[i].inputChannel == inputChannel) {
3997 monitors.erase(monitors.begin() + i);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003998 break;
3999 }
4000 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004001 if (monitors.empty()) {
4002 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004003 } else {
4004 ++it;
4005 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004006 }
4007}
4008
Michael Wright3dd60e22019-03-27 22:06:44 +00004009status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4010 { // acquire lock
4011 std::scoped_lock _l(mLock);
4012 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4013
4014 if (!foundDisplayId) {
4015 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4016 return BAD_VALUE;
4017 }
4018 int32_t displayId = foundDisplayId.value();
4019
4020 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4021 if (stateIndex < 0) {
4022 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4023 return BAD_VALUE;
4024 }
4025
4026 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4027 std::optional<int32_t> foundDeviceId;
4028 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
4029 if (touchedMonitor.monitor.inputChannel->getToken() == token) {
4030 foundDeviceId = state.deviceId;
4031 }
4032 }
4033 if (!foundDeviceId || !state.down) {
4034 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
4035 " Ignoring.");
4036 return BAD_VALUE;
4037 }
4038 int32_t deviceId = foundDeviceId.value();
4039
4040 // Send cancel events to all the input channels we're stealing from.
4041 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4042 "gesture monitor stole pointer stream");
4043 options.deviceId = deviceId;
4044 options.displayId = displayId;
4045 for (const TouchedWindow& window : state.windows) {
4046 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
4047 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4048 }
4049 // Then clear the current touch state so we stop dispatching to them as well.
4050 state.filterNonMonitors();
4051 }
4052 return OK;
4053}
4054
4055
4056std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4057 const sp<IBinder>& token) {
4058 for (const auto& it : mGestureMonitorsByDisplay) {
4059 const std::vector<Monitor>& monitors = it.second;
4060 for (const Monitor& monitor : monitors) {
4061 if (monitor.inputChannel->getToken() == token) {
4062 return it.first;
4063 }
4064 }
4065 }
4066 return std::nullopt;
4067}
4068
Michael Wrightd02c5b62014-02-10 15:10:22 -08004069ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Robert Carr4e670e52018-08-15 13:26:12 -07004070 if (inputChannel == nullptr) {
Arthur Hung3b413f22018-10-26 18:05:34 +08004071 return -1;
4072 }
4073
Robert Carr4e670e52018-08-15 13:26:12 -07004074 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
4075 sp<Connection> connection = mConnectionsByFd.valueAt(i);
4076 if (connection->inputChannel->getToken() == inputChannel->getToken()) {
4077 return i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004078 }
4079 }
Robert Carr4e670e52018-08-15 13:26:12 -07004080
Michael Wrightd02c5b62014-02-10 15:10:22 -08004081 return -1;
4082}
4083
4084void InputDispatcher::onDispatchCycleFinishedLocked(
4085 nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
4086 CommandEntry* commandEntry = postCommandLocked(
4087 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
4088 commandEntry->connection = connection;
4089 commandEntry->eventTime = currentTime;
4090 commandEntry->seq = seq;
4091 commandEntry->handled = handled;
4092}
4093
4094void InputDispatcher::onDispatchCycleBrokenLocked(
4095 nsecs_t currentTime, const sp<Connection>& connection) {
4096 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004097 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004098
4099 CommandEntry* commandEntry = postCommandLocked(
4100 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
4101 commandEntry->connection = connection;
4102}
4103
chaviw0c06c6e2019-01-09 13:27:07 -08004104void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
4105 const sp<InputWindowHandle>& newFocus) {
4106 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4107 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Robert Carrf759f162018-11-13 12:57:11 -08004108 CommandEntry* commandEntry = postCommandLocked(
4109 & InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004110 commandEntry->oldToken = oldToken;
4111 commandEntry->newToken = newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004112}
4113
Michael Wrightd02c5b62014-02-10 15:10:22 -08004114void InputDispatcher::onANRLocked(
4115 nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
4116 const sp<InputWindowHandle>& windowHandle,
4117 nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
4118 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4119 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4120 ALOGI("Application is not responding: %s. "
4121 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004122 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004123 dispatchLatency, waitDuration, reason);
4124
4125 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004126 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004127 struct tm tm;
4128 localtime_r(&t, &tm);
4129 char timestr[64];
4130 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4131 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004132 mLastANRState += INDENT "ANR:\n";
4133 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
4134 mLastANRState += StringPrintf(INDENT2 "Window: %s\n",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004135 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004136 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4137 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4138 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004139 dumpDispatchStateLocked(mLastANRState);
4140
4141 CommandEntry* commandEntry = postCommandLocked(
4142 & InputDispatcher::doNotifyANRLockedInterruptible);
4143 commandEntry->inputApplicationHandle = applicationHandle;
Robert Carr5c8a0262018-10-03 16:30:44 -07004144 commandEntry->inputChannel = windowHandle != nullptr ?
4145 getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004146 commandEntry->reason = reason;
4147}
4148
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004149void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible (
Michael Wrightd02c5b62014-02-10 15:10:22 -08004150 CommandEntry* commandEntry) {
4151 mLock.unlock();
4152
4153 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4154
4155 mLock.lock();
4156}
4157
4158void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
4159 CommandEntry* commandEntry) {
4160 sp<Connection> connection = commandEntry->connection;
4161
4162 if (connection->status != Connection::STATUS_ZOMBIE) {
4163 mLock.unlock();
4164
Robert Carr803535b2018-08-02 16:38:15 -07004165 mPolicy->notifyInputChannelBroken(connection->inputChannel->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004166
4167 mLock.lock();
4168 }
4169}
4170
Robert Carrf759f162018-11-13 12:57:11 -08004171void InputDispatcher::doNotifyFocusChangedLockedInterruptible(
4172 CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004173 sp<IBinder> oldToken = commandEntry->oldToken;
4174 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004175 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004176 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004177 mLock.lock();
4178}
4179
Michael Wrightd02c5b62014-02-10 15:10:22 -08004180void InputDispatcher::doNotifyANRLockedInterruptible(
4181 CommandEntry* commandEntry) {
4182 mLock.unlock();
4183
4184 nsecs_t newTimeout = mPolicy->notifyANR(
Robert Carr803535b2018-08-02 16:38:15 -07004185 commandEntry->inputApplicationHandle,
4186 commandEntry->inputChannel ? commandEntry->inputChannel->getToken() : nullptr,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004187 commandEntry->reason);
4188
4189 mLock.lock();
4190
4191 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
Robert Carr803535b2018-08-02 16:38:15 -07004192 commandEntry->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004193}
4194
4195void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4196 CommandEntry* commandEntry) {
4197 KeyEntry* entry = commandEntry->keyEntry;
4198
4199 KeyEvent event;
4200 initializeKeyEvent(&event, entry);
4201
4202 mLock.unlock();
4203
Michael Wright2b3c3302018-03-02 17:19:13 +00004204 android::base::Timer t;
Robert Carr803535b2018-08-02 16:38:15 -07004205 sp<IBinder> token = commandEntry->inputChannel != nullptr ?
4206 commandEntry->inputChannel->getToken() : nullptr;
4207 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004208 &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004209 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4210 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
4211 std::to_string(t.duration().count()).c_str());
4212 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004213
4214 mLock.lock();
4215
4216 if (delay < 0) {
4217 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4218 } else if (!delay) {
4219 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4220 } else {
4221 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4222 entry->interceptKeyWakeupTime = now() + delay;
4223 }
4224 entry->release();
4225}
4226
chaviwfd6d3512019-03-25 13:23:49 -07004227void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4228 mLock.unlock();
4229 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4230 mLock.lock();
4231}
4232
Michael Wrightd02c5b62014-02-10 15:10:22 -08004233void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
4234 CommandEntry* commandEntry) {
4235 sp<Connection> connection = commandEntry->connection;
4236 nsecs_t finishTime = commandEntry->eventTime;
4237 uint32_t seq = commandEntry->seq;
4238 bool handled = commandEntry->handled;
4239
4240 // Handle post-event policy actions.
4241 DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
4242 if (dispatchEntry) {
4243 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4244 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004245 std::string msg =
4246 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004247 connection->getWindowName().c_str(), eventDuration * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004248 dispatchEntry->eventEntry->appendDescription(msg);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004249 ALOGI("%s", msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004250 }
4251
4252 bool restartEvent;
4253 if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
4254 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4255 restartEvent = afterKeyEventLockedInterruptible(connection,
4256 dispatchEntry, keyEntry, handled);
4257 } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
4258 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4259 restartEvent = afterMotionEventLockedInterruptible(connection,
4260 dispatchEntry, motionEntry, handled);
4261 } else {
4262 restartEvent = false;
4263 }
4264
4265 // Dequeue the event and start the next cycle.
4266 // Note that because the lock might have been released, it is possible that the
4267 // contents of the wait queue to have been drained, so we need to double-check
4268 // a few things.
4269 if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
4270 connection->waitQueue.dequeue(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004271 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004272 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
4273 connection->outboundQueue.enqueueAtHead(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004274 traceOutboundQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004275 } else {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08004276 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004277 }
4278 }
4279
4280 // Start the next dispatch cycle for this connection.
4281 startDispatchCycleLocked(now(), connection);
4282 }
4283}
4284
4285bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
4286 DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004287 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004288 if (!handled) {
4289 // Report the key as unhandled, since the fallback was not handled.
4290 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4291 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004292 return false;
4293 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004294
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004295 // Get the fallback key state.
4296 // Clear it out after dispatching the UP.
4297 int32_t originalKeyCode = keyEntry->keyCode;
4298 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4299 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4300 connection->inputState.removeFallbackKey(originalKeyCode);
4301 }
4302
4303 if (handled || !dispatchEntry->hasForegroundTarget()) {
4304 // If the application handles the original key for which we previously
4305 // generated a fallback or if the window is not a foreground window,
4306 // then cancel the associated fallback key, if any.
4307 if (fallbackKeyCode != -1) {
4308 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004309#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004310 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004311 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4312 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4313 keyEntry->policyFlags);
4314#endif
4315 KeyEvent event;
4316 initializeKeyEvent(&event, keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004317 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004318
4319 mLock.unlock();
4320
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004321 mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4322 &event, keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004323
4324 mLock.lock();
4325
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004326 // Cancel the fallback key.
4327 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004328 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004329 "application handled the original non-fallback key "
4330 "or is no longer a foreground target, "
4331 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004332 options.keyCode = fallbackKeyCode;
4333 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004334 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004335 connection->inputState.removeFallbackKey(originalKeyCode);
4336 }
4337 } else {
4338 // If the application did not handle a non-fallback key, first check
4339 // that we are in a good state to perform unhandled key event processing
4340 // Then ask the policy what to do with it.
4341 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
4342 && keyEntry->repeatCount == 0;
4343 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004344#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004345 ALOGD("Unhandled key event: Skipping unhandled key event processing "
4346 "since this is not an initial down. "
4347 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4348 originalKeyCode, keyEntry->action, keyEntry->repeatCount,
4349 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004350#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004351 return false;
4352 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004353
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004354 // Dispatch the unhandled key to the policy.
4355#if DEBUG_OUTBOUND_EVENT_DETAILS
4356 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
4357 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4358 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4359 keyEntry->policyFlags);
4360#endif
4361 KeyEvent event;
4362 initializeKeyEvent(&event, keyEntry);
4363
4364 mLock.unlock();
4365
4366 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4367 &event, keyEntry->policyFlags, &event);
4368
4369 mLock.lock();
4370
4371 if (connection->status != Connection::STATUS_NORMAL) {
4372 connection->inputState.removeFallbackKey(originalKeyCode);
4373 return false;
4374 }
4375
4376 // Latch the fallback keycode for this key on an initial down.
4377 // The fallback keycode cannot change at any other point in the lifecycle.
4378 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004379 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004380 fallbackKeyCode = event.getKeyCode();
4381 } else {
4382 fallbackKeyCode = AKEYCODE_UNKNOWN;
4383 }
4384 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4385 }
4386
4387 ALOG_ASSERT(fallbackKeyCode != -1);
4388
4389 // Cancel the fallback key if the policy decides not to send it anymore.
4390 // We will continue to dispatch the key to the policy but we will no
4391 // longer dispatch a fallback key to the application.
4392 if (fallbackKeyCode != AKEYCODE_UNKNOWN
4393 && (!fallback || fallbackKeyCode != event.getKeyCode())) {
4394#if DEBUG_OUTBOUND_EVENT_DETAILS
4395 if (fallback) {
4396 ALOGD("Unhandled key event: Policy requested to send key %d"
4397 "as a fallback for %d, but on the DOWN it had requested "
4398 "to send %d instead. Fallback canceled.",
4399 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
4400 } else {
4401 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
4402 "but on the DOWN it had requested to send %d. "
4403 "Fallback canceled.",
4404 originalKeyCode, fallbackKeyCode);
4405 }
4406#endif
4407
4408 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4409 "canceling fallback, policy no longer desires it");
4410 options.keyCode = fallbackKeyCode;
4411 synthesizeCancelationEventsForConnectionLocked(connection, options);
4412
4413 fallback = false;
4414 fallbackKeyCode = AKEYCODE_UNKNOWN;
4415 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
4416 connection->inputState.setFallbackKey(originalKeyCode,
4417 fallbackKeyCode);
4418 }
4419 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004420
4421#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004422 {
4423 std::string msg;
4424 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4425 connection->inputState.getFallbackKeys();
4426 for (size_t i = 0; i < fallbackKeys.size(); i++) {
4427 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i),
4428 fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004429 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004430 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
4431 fallbackKeys.size(), msg.c_str());
4432 }
4433#endif
4434
4435 if (fallback) {
4436 // Restart the dispatch cycle using the fallback key.
4437 keyEntry->eventTime = event.getEventTime();
4438 keyEntry->deviceId = event.getDeviceId();
4439 keyEntry->source = event.getSource();
4440 keyEntry->displayId = event.getDisplayId();
4441 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4442 keyEntry->keyCode = fallbackKeyCode;
4443 keyEntry->scanCode = event.getScanCode();
4444 keyEntry->metaState = event.getMetaState();
4445 keyEntry->repeatCount = event.getRepeatCount();
4446 keyEntry->downTime = event.getDownTime();
4447 keyEntry->syntheticRepeat = false;
4448
4449#if DEBUG_OUTBOUND_EVENT_DETAILS
4450 ALOGD("Unhandled key event: Dispatching fallback key. "
4451 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4452 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
4453#endif
4454 return true; // restart the event
4455 } else {
4456#if DEBUG_OUTBOUND_EVENT_DETAILS
4457 ALOGD("Unhandled key event: No fallback key.");
4458#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004459
4460 // Report the key as unhandled, since there is no fallback key.
4461 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004462 }
4463 }
4464 return false;
4465}
4466
4467bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
4468 DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
4469 return false;
4470}
4471
4472void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4473 mLock.unlock();
4474
4475 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4476
4477 mLock.lock();
4478}
4479
4480void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004481 event->initialize(entry->deviceId, entry->source, entry->displayId, entry->action, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004482 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
4483 entry->downTime, entry->eventTime);
4484}
4485
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004486void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry* entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004487 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
4488 // TODO Write some statistics about how long we spend waiting.
4489}
4490
4491void InputDispatcher::traceInboundQueueLengthLocked() {
4492 if (ATRACE_ENABLED()) {
4493 ATRACE_INT("iq", mInboundQueue.count());
4494 }
4495}
4496
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004497void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004498 if (ATRACE_ENABLED()) {
4499 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004500 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004501 ATRACE_INT(counterName, connection->outboundQueue.count());
4502 }
4503}
4504
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004505void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004506 if (ATRACE_ENABLED()) {
4507 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004508 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004509 ATRACE_INT(counterName, connection->waitQueue.count());
4510 }
4511}
4512
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004513void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004514 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004515
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004516 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004517 dumpDispatchStateLocked(dump);
4518
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004519 if (!mLastANRState.empty()) {
4520 dump += "\nInput Dispatcher State at time of last ANR:\n";
4521 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004522 }
4523}
4524
4525void InputDispatcher::monitor() {
4526 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004527 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004528 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004529 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004530}
4531
4532
Michael Wrightd02c5b62014-02-10 15:10:22 -08004533// --- InputDispatcher::InjectionState ---
4534
4535InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
4536 refCount(1),
4537 injectorPid(injectorPid), injectorUid(injectorUid),
4538 injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
4539 pendingForegroundDispatches(0) {
4540}
4541
4542InputDispatcher::InjectionState::~InjectionState() {
4543}
4544
4545void InputDispatcher::InjectionState::release() {
4546 refCount -= 1;
4547 if (refCount == 0) {
4548 delete this;
4549 } else {
4550 ALOG_ASSERT(refCount > 0);
4551 }
4552}
4553
4554
4555// --- InputDispatcher::EventEntry ---
4556
Prabir Pradhan42611e02018-11-27 14:04:02 -08004557InputDispatcher::EventEntry::EventEntry(uint32_t sequenceNum, int32_t type,
4558 nsecs_t eventTime, uint32_t policyFlags) :
4559 sequenceNum(sequenceNum), refCount(1), type(type), eventTime(eventTime),
4560 policyFlags(policyFlags), injectionState(nullptr), dispatchInProgress(false) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004561}
4562
4563InputDispatcher::EventEntry::~EventEntry() {
4564 releaseInjectionState();
4565}
4566
4567void InputDispatcher::EventEntry::release() {
4568 refCount -= 1;
4569 if (refCount == 0) {
4570 delete this;
4571 } else {
4572 ALOG_ASSERT(refCount > 0);
4573 }
4574}
4575
4576void InputDispatcher::EventEntry::releaseInjectionState() {
4577 if (injectionState) {
4578 injectionState->release();
Yi Kong9b14ac62018-07-17 13:48:38 -07004579 injectionState = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004580 }
4581}
4582
4583
4584// --- InputDispatcher::ConfigurationChangedEntry ---
4585
Prabir Pradhan42611e02018-11-27 14:04:02 -08004586InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(
4587 uint32_t sequenceNum, nsecs_t eventTime) :
4588 EventEntry(sequenceNum, TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004589}
4590
4591InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
4592}
4593
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004594void InputDispatcher::ConfigurationChangedEntry::appendDescription(std::string& msg) const {
4595 msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004596}
4597
4598
4599// --- InputDispatcher::DeviceResetEntry ---
4600
Prabir Pradhan42611e02018-11-27 14:04:02 -08004601InputDispatcher::DeviceResetEntry::DeviceResetEntry(
4602 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId) :
4603 EventEntry(sequenceNum, TYPE_DEVICE_RESET, eventTime, 0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004604 deviceId(deviceId) {
4605}
4606
4607InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
4608}
4609
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004610void InputDispatcher::DeviceResetEntry::appendDescription(std::string& msg) const {
4611 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x",
Michael Wrightd02c5b62014-02-10 15:10:22 -08004612 deviceId, policyFlags);
4613}
4614
4615
4616// --- InputDispatcher::KeyEntry ---
4617
Prabir Pradhan42611e02018-11-27 14:04:02 -08004618InputDispatcher::KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004619 int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004620 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
4621 int32_t repeatCount, nsecs_t downTime) :
Prabir Pradhan42611e02018-11-27 14:04:02 -08004622 EventEntry(sequenceNum, TYPE_KEY, eventTime, policyFlags),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004623 deviceId(deviceId), source(source), displayId(displayId), action(action), flags(flags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004624 keyCode(keyCode), scanCode(scanCode), metaState(metaState),
4625 repeatCount(repeatCount), downTime(downTime),
4626 syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
4627 interceptKeyWakeupTime(0) {
4628}
4629
4630InputDispatcher::KeyEntry::~KeyEntry() {
4631}
4632
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004633void InputDispatcher::KeyEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004634 msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004635 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
4636 "repeatCount=%d), policyFlags=0x%08x",
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004637 deviceId, source, displayId, keyActionToString(action).c_str(), flags, keyCode,
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004638 scanCode, metaState, repeatCount, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004639}
4640
4641void InputDispatcher::KeyEntry::recycle() {
4642 releaseInjectionState();
4643
4644 dispatchInProgress = false;
4645 syntheticRepeat = false;
4646 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
4647 interceptKeyWakeupTime = 0;
4648}
4649
4650
4651// --- InputDispatcher::MotionEntry ---
4652
Garfield Tan00f511d2019-06-12 16:55:40 -07004653InputDispatcher::MotionEntry::MotionEntry(
4654 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
4655 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004656 int32_t flags, int32_t metaState, int32_t buttonState, MotionClassification classification,
Garfield Tan00f511d2019-06-12 16:55:40 -07004657 int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition,
4658 float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
Jeff Brownf086ddb2014-02-11 14:28:48 -08004659 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
Garfield Tan00f511d2019-06-12 16:55:40 -07004660 float xOffset, float yOffset)
4661 : EventEntry(sequenceNum, TYPE_MOTION, eventTime, policyFlags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004662 eventTime(eventTime),
Garfield Tan00f511d2019-06-12 16:55:40 -07004663 deviceId(deviceId),
4664 source(source),
4665 displayId(displayId),
4666 action(action),
4667 actionButton(actionButton),
4668 flags(flags),
4669 metaState(metaState),
4670 buttonState(buttonState),
4671 classification(classification),
4672 edgeFlags(edgeFlags),
4673 xPrecision(xPrecision),
4674 yPrecision(yPrecision),
4675 xCursorPosition(xCursorPosition),
4676 yCursorPosition(yCursorPosition),
4677 downTime(downTime),
4678 pointerCount(pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004679 for (uint32_t i = 0; i < pointerCount; i++) {
4680 this->pointerProperties[i].copyFrom(pointerProperties[i]);
4681 this->pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004682 if (xOffset || yOffset) {
4683 this->pointerCoords[i].applyOffset(xOffset, yOffset);
4684 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004685 }
4686}
4687
4688InputDispatcher::MotionEntry::~MotionEntry() {
4689}
4690
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004691void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004692 msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07004693 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
4694 "buttonState=0x%08x, "
4695 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
4696 "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
4697 deviceId, source, displayId, motionActionToString(action).c_str(),
4698 actionButton, flags, metaState, buttonState,
4699 motionClassificationToString(classification), edgeFlags, xPrecision,
4700 yPrecision, xCursorPosition, yCursorPosition);
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004701
Michael Wrightd02c5b62014-02-10 15:10:22 -08004702 for (uint32_t i = 0; i < pointerCount; i++) {
4703 if (i) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004704 msg += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004705 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004706 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004707 pointerCoords[i].getX(), pointerCoords[i].getY());
4708 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004709 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004710}
4711
4712
4713// --- InputDispatcher::DispatchEntry ---
4714
4715volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
4716
4717InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
Robert Carre07e1032018-11-26 12:55:53 -08004718 int32_t targetFlags, float xOffset, float yOffset, float globalScaleFactor,
4719 float windowXScale, float windowYScale) :
Michael Wrightd02c5b62014-02-10 15:10:22 -08004720 seq(nextSeq()),
4721 eventEntry(eventEntry), targetFlags(targetFlags),
Robert Carre07e1032018-11-26 12:55:53 -08004722 xOffset(xOffset), yOffset(yOffset), globalScaleFactor(globalScaleFactor),
4723 windowXScale(windowXScale), windowYScale(windowYScale),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004724 deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
4725 eventEntry->refCount += 1;
4726}
4727
4728InputDispatcher::DispatchEntry::~DispatchEntry() {
4729 eventEntry->release();
4730}
4731
4732uint32_t InputDispatcher::DispatchEntry::nextSeq() {
4733 // Sequence number 0 is reserved and will never be returned.
4734 uint32_t seq;
4735 do {
4736 seq = android_atomic_inc(&sNextSeqAtomic);
4737 } while (!seq);
4738 return seq;
4739}
4740
4741
4742// --- InputDispatcher::InputState ---
4743
4744InputDispatcher::InputState::InputState() {
4745}
4746
4747InputDispatcher::InputState::~InputState() {
4748}
4749
4750bool InputDispatcher::InputState::isNeutral() const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004751 return mKeyMementos.empty() && mMotionMementos.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004752}
4753
4754bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
4755 int32_t displayId) const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004756 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004757 if (memento.deviceId == deviceId
4758 && memento.source == source
4759 && memento.displayId == displayId
4760 && memento.hovering) {
4761 return true;
4762 }
4763 }
4764 return false;
4765}
4766
4767bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
4768 int32_t action, int32_t flags) {
4769 switch (action) {
4770 case AKEY_EVENT_ACTION_UP: {
4771 if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
4772 for (size_t i = 0; i < mFallbackKeys.size(); ) {
4773 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
4774 mFallbackKeys.removeItemsAt(i);
4775 } else {
4776 i += 1;
4777 }
4778 }
4779 }
4780 ssize_t index = findKeyMemento(entry);
4781 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004782 mKeyMementos.erase(mKeyMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004783 return true;
4784 }
4785 /* FIXME: We can't just drop the key up event because that prevents creating
4786 * popup windows that are automatically shown when a key is held and then
4787 * dismissed when the key is released. The problem is that the popup will
4788 * not have received the original key down, so the key up will be considered
4789 * to be inconsistent with its observed state. We could perhaps handle this
4790 * by synthesizing a key down but that will cause other problems.
4791 *
4792 * So for now, allow inconsistent key up events to be dispatched.
4793 *
4794#if DEBUG_OUTBOUND_EVENT_DETAILS
4795 ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
4796 "keyCode=%d, scanCode=%d",
4797 entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
4798#endif
4799 return false;
4800 */
4801 return true;
4802 }
4803
4804 case AKEY_EVENT_ACTION_DOWN: {
4805 ssize_t index = findKeyMemento(entry);
4806 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004807 mKeyMementos.erase(mKeyMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004808 }
4809 addKeyMemento(entry, flags);
4810 return true;
4811 }
4812
4813 default:
4814 return true;
4815 }
4816}
4817
4818bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
4819 int32_t action, int32_t flags) {
4820 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
4821 switch (actionMasked) {
4822 case AMOTION_EVENT_ACTION_UP:
4823 case AMOTION_EVENT_ACTION_CANCEL: {
4824 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4825 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004826 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004827 return true;
4828 }
4829#if DEBUG_OUTBOUND_EVENT_DETAILS
4830 ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004831 "displayId=%" PRId32 ", actionMasked=%d",
4832 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004833#endif
4834 return false;
4835 }
4836
4837 case AMOTION_EVENT_ACTION_DOWN: {
4838 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4839 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004840 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004841 }
4842 addMotionMemento(entry, flags, false /*hovering*/);
4843 return true;
4844 }
4845
4846 case AMOTION_EVENT_ACTION_POINTER_UP:
4847 case AMOTION_EVENT_ACTION_POINTER_DOWN:
4848 case AMOTION_EVENT_ACTION_MOVE: {
Michael Wright38dcdff2014-03-19 12:06:10 -07004849 if (entry->source & AINPUT_SOURCE_CLASS_NAVIGATION) {
4850 // Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need to
4851 // generate cancellation events for these since they're based in relative rather than
4852 // absolute units.
4853 return true;
4854 }
4855
Michael Wrightd02c5b62014-02-10 15:10:22 -08004856 ssize_t index = findMotionMemento(entry, false /*hovering*/);
Michael Wright38dcdff2014-03-19 12:06:10 -07004857
4858 if (entry->source & AINPUT_SOURCE_CLASS_JOYSTICK) {
4859 // Joysticks can send MOVE events without a corresponding DOWN or UP. Since all
4860 // joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral. Any
4861 // other value and we need to track the motion so we can send cancellation events for
4862 // anything generating fallback events (e.g. DPad keys for joystick movements).
4863 if (index >= 0) {
4864 if (entry->pointerCoords[0].isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004865 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wright38dcdff2014-03-19 12:06:10 -07004866 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004867 MotionMemento& memento = mMotionMementos[index];
Michael Wright38dcdff2014-03-19 12:06:10 -07004868 memento.setPointers(entry);
4869 }
4870 } else if (!entry->pointerCoords[0].isEmpty()) {
4871 addMotionMemento(entry, flags, false /*hovering*/);
4872 }
4873
4874 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
4875 return true;
4876 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004877 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004878 MotionMemento& memento = mMotionMementos[index];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004879 memento.setPointers(entry);
4880 return true;
4881 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004882#if DEBUG_OUTBOUND_EVENT_DETAILS
4883 ALOGD("Dropping inconsistent motion pointer up/down or move event: "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004884 "deviceId=%d, source=%08x, displayId=%" PRId32 ", actionMasked=%d",
4885 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004886#endif
4887 return false;
4888 }
4889
4890 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
4891 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4892 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004893 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004894 return true;
4895 }
4896#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004897 ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x, "
4898 "displayId=%" PRId32,
4899 entry->deviceId, entry->source, entry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004900#endif
4901 return false;
4902 }
4903
4904 case AMOTION_EVENT_ACTION_HOVER_ENTER:
4905 case AMOTION_EVENT_ACTION_HOVER_MOVE: {
4906 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4907 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004908 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004909 }
4910 addMotionMemento(entry, flags, true /*hovering*/);
4911 return true;
4912 }
4913
4914 default:
4915 return true;
4916 }
4917}
4918
4919ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
4920 for (size_t i = 0; i < mKeyMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004921 const KeyMemento& memento = mKeyMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004922 if (memento.deviceId == entry->deviceId
4923 && memento.source == entry->source
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004924 && memento.displayId == entry->displayId
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925 && memento.keyCode == entry->keyCode
4926 && memento.scanCode == entry->scanCode) {
4927 return i;
4928 }
4929 }
4930 return -1;
4931}
4932
4933ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
4934 bool hovering) const {
4935 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004936 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004937 if (memento.deviceId == entry->deviceId
4938 && memento.source == entry->source
4939 && memento.displayId == entry->displayId
4940 && memento.hovering == hovering) {
4941 return i;
4942 }
4943 }
4944 return -1;
4945}
4946
4947void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004948 KeyMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004949 memento.deviceId = entry->deviceId;
4950 memento.source = entry->source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004951 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004952 memento.keyCode = entry->keyCode;
4953 memento.scanCode = entry->scanCode;
4954 memento.metaState = entry->metaState;
4955 memento.flags = flags;
4956 memento.downTime = entry->downTime;
4957 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004958 mKeyMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004959}
4960
4961void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
4962 int32_t flags, bool hovering) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004963 MotionMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004964 memento.deviceId = entry->deviceId;
4965 memento.source = entry->source;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004966 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004967 memento.flags = flags;
4968 memento.xPrecision = entry->xPrecision;
4969 memento.yPrecision = entry->yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -07004970 memento.xCursorPosition = entry->xCursorPosition;
4971 memento.yCursorPosition = entry->yCursorPosition;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004972 memento.downTime = entry->downTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004973 memento.setPointers(entry);
4974 memento.hovering = hovering;
4975 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004976 mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004977}
4978
4979void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
4980 pointerCount = entry->pointerCount;
4981 for (uint32_t i = 0; i < entry->pointerCount; i++) {
4982 pointerProperties[i].copyFrom(entry->pointerProperties[i]);
4983 pointerCoords[i].copyFrom(entry->pointerCoords[i]);
4984 }
4985}
4986
4987void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004988 std::vector<EventEntry*>& outEvents, const CancelationOptions& options) {
4989 for (KeyMemento& memento : mKeyMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004990 if (shouldCancelKey(memento, options)) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004991 outEvents.push_back(new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004992 memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004993 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
4994 memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
4995 }
4996 }
4997
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004998 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004999 if (shouldCancelMotion(memento, options)) {
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08005000 const int32_t action = memento.hovering ?
5001 AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
Garfield Tan00f511d2019-06-12 16:55:40 -07005002 outEvents.push_back(
5003 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, memento.deviceId,
5004 memento.source, memento.displayId, memento.policyFlags, action,
5005 0 /*actionButton*/, memento.flags, AMETA_NONE,
5006 0 /*buttonState*/, MotionClassification::NONE,
5007 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
5008 memento.yPrecision, memento.xCursorPosition,
5009 memento.yCursorPosition, memento.downTime, memento.pointerCount,
5010 memento.pointerProperties, memento.pointerCoords, 0 /*xOffset*/,
5011 0 /*yOffset*/));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005012 }
5013 }
5014}
5015
5016void InputDispatcher::InputState::clear() {
5017 mKeyMementos.clear();
5018 mMotionMementos.clear();
5019 mFallbackKeys.clear();
5020}
5021
5022void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
5023 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005024 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005025 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
5026 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005027 const MotionMemento& otherMemento = other.mMotionMementos[j];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005028 if (memento.deviceId == otherMemento.deviceId
5029 && memento.source == otherMemento.source
5030 && memento.displayId == otherMemento.displayId) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005031 other.mMotionMementos.erase(other.mMotionMementos.begin() + j);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005032 } else {
5033 j += 1;
5034 }
5035 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005036 other.mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005037 }
5038 }
5039}
5040
5041int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
5042 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5043 return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
5044}
5045
5046void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
5047 int32_t fallbackKeyCode) {
5048 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5049 if (index >= 0) {
5050 mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
5051 } else {
5052 mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
5053 }
5054}
5055
5056void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
5057 mFallbackKeys.removeItem(originalKeyCode);
5058}
5059
5060bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
5061 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005062 if (options.keyCode && memento.keyCode != options.keyCode.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005063 return false;
5064 }
5065
Michael Wright3dd60e22019-03-27 22:06:44 +00005066 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5067 return false;
5068 }
5069
5070 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005071 return false;
5072 }
5073
5074 switch (options.mode) {
5075 case CancelationOptions::CANCEL_ALL_EVENTS:
5076 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5077 return true;
5078 case CancelationOptions::CANCEL_FALLBACK_EVENTS:
5079 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
5080 default:
5081 return false;
5082 }
5083}
5084
5085bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
5086 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005087 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5088 return false;
5089 }
5090
5091 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005092 return false;
5093 }
5094
5095 switch (options.mode) {
5096 case CancelationOptions::CANCEL_ALL_EVENTS:
5097 return true;
5098 case CancelationOptions::CANCEL_POINTER_EVENTS:
5099 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
5100 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5101 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
5102 default:
5103 return false;
5104 }
5105}
5106
5107
5108// --- InputDispatcher::Connection ---
5109
Robert Carr803535b2018-08-02 16:38:15 -07005110InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel, bool monitor) :
5111 status(STATUS_NORMAL), inputChannel(inputChannel),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005112 monitor(monitor),
5113 inputPublisher(inputChannel), inputPublisherBlocked(false) {
5114}
5115
5116InputDispatcher::Connection::~Connection() {
5117}
5118
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005119const std::string InputDispatcher::Connection::getWindowName() const {
Robert Carr803535b2018-08-02 16:38:15 -07005120 if (inputChannel != nullptr) {
5121 return inputChannel->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005122 }
5123 if (monitor) {
5124 return "monitor";
5125 }
5126 return "?";
5127}
5128
5129const char* InputDispatcher::Connection::getStatusLabel() const {
5130 switch (status) {
5131 case STATUS_NORMAL:
5132 return "NORMAL";
5133
5134 case STATUS_BROKEN:
5135 return "BROKEN";
5136
5137 case STATUS_ZOMBIE:
5138 return "ZOMBIE";
5139
5140 default:
5141 return "UNKNOWN";
5142 }
5143}
5144
5145InputDispatcher::DispatchEntry* InputDispatcher::Connection::findWaitQueueEntry(uint32_t seq) {
Yi Kong9b14ac62018-07-17 13:48:38 -07005146 for (DispatchEntry* entry = waitQueue.head; entry != nullptr; entry = entry->next) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005147 if (entry->seq == seq) {
5148 return entry;
5149 }
5150 }
Yi Kong9b14ac62018-07-17 13:48:38 -07005151 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005152}
5153
Michael Wright3dd60e22019-03-27 22:06:44 +00005154// --- InputDispatcher::Monitor
5155InputDispatcher::Monitor::Monitor(const sp<InputChannel>& inputChannel) :
5156 inputChannel(inputChannel) {
5157}
5158
Michael Wrightd02c5b62014-02-10 15:10:22 -08005159
5160// --- InputDispatcher::CommandEntry ---
Michael Wright3dd60e22019-03-27 22:06:44 +00005161//
Michael Wrightd02c5b62014-02-10 15:10:22 -08005162InputDispatcher::CommandEntry::CommandEntry(Command command) :
Yi Kong9b14ac62018-07-17 13:48:38 -07005163 command(command), eventTime(0), keyEntry(nullptr), userActivityEventType(0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005164 seq(0), handled(false) {
5165}
5166
5167InputDispatcher::CommandEntry::~CommandEntry() {
5168}
5169
Michael Wright3dd60e22019-03-27 22:06:44 +00005170// --- InputDispatcher::TouchedMonitor ---
5171InputDispatcher::TouchedMonitor::TouchedMonitor(const Monitor& monitor, float xOffset,
5172 float yOffset) : monitor(monitor), xOffset(xOffset), yOffset(yOffset) {
5173}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005174
5175// --- InputDispatcher::TouchState ---
5176
5177InputDispatcher::TouchState::TouchState() :
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005178 down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005179}
5180
5181InputDispatcher::TouchState::~TouchState() {
5182}
5183
5184void InputDispatcher::TouchState::reset() {
5185 down = false;
5186 split = false;
5187 deviceId = -1;
5188 source = 0;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005189 displayId = ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005190 windows.clear();
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005191 portalWindows.clear();
Michael Wright3dd60e22019-03-27 22:06:44 +00005192 gestureMonitors.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005193}
5194
5195void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
5196 down = other.down;
5197 split = other.split;
5198 deviceId = other.deviceId;
5199 source = other.source;
5200 displayId = other.displayId;
5201 windows = other.windows;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005202 portalWindows = other.portalWindows;
Michael Wright3dd60e22019-03-27 22:06:44 +00005203 gestureMonitors = other.gestureMonitors;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005204}
5205
5206void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
5207 int32_t targetFlags, BitSet32 pointerIds) {
5208 if (targetFlags & InputTarget::FLAG_SPLIT) {
5209 split = true;
5210 }
5211
5212 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005213 TouchedWindow& touchedWindow = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005214 if (touchedWindow.windowHandle == windowHandle) {
5215 touchedWindow.targetFlags |= targetFlags;
5216 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
5217 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
5218 }
5219 touchedWindow.pointerIds.value |= pointerIds.value;
5220 return;
5221 }
5222 }
5223
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005224 TouchedWindow touchedWindow;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005225 touchedWindow.windowHandle = windowHandle;
5226 touchedWindow.targetFlags = targetFlags;
5227 touchedWindow.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005228 windows.push_back(touchedWindow);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005229}
5230
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005231void InputDispatcher::TouchState::addPortalWindow(const sp<InputWindowHandle>& windowHandle) {
5232 size_t numWindows = portalWindows.size();
5233 for (size_t i = 0; i < numWindows; i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005234 if (portalWindows[i] == windowHandle) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005235 return;
5236 }
5237 }
5238 portalWindows.push_back(windowHandle);
5239}
5240
Michael Wright3dd60e22019-03-27 22:06:44 +00005241void InputDispatcher::TouchState::addGestureMonitors(
5242 const std::vector<TouchedMonitor>& newMonitors) {
5243 const size_t newSize = gestureMonitors.size() + newMonitors.size();
5244 gestureMonitors.reserve(newSize);
5245 gestureMonitors.insert(std::end(gestureMonitors),
5246 std::begin(newMonitors), std::end(newMonitors));
5247}
5248
Michael Wrightd02c5b62014-02-10 15:10:22 -08005249void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
5250 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005251 if (windows[i].windowHandle == windowHandle) {
5252 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005253 return;
5254 }
5255 }
5256}
5257
Robert Carr803535b2018-08-02 16:38:15 -07005258void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) {
5259 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005260 if (windows[i].windowHandle->getToken() == token) {
5261 windows.erase(windows.begin() + i);
Robert Carr803535b2018-08-02 16:38:15 -07005262 return;
5263 }
5264 }
5265}
5266
Michael Wrightd02c5b62014-02-10 15:10:22 -08005267void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
5268 for (size_t i = 0 ; i < windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005269 TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005270 if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
5271 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
5272 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
5273 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
5274 i += 1;
5275 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005276 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005277 }
5278 }
5279}
5280
Michael Wright3dd60e22019-03-27 22:06:44 +00005281void InputDispatcher::TouchState::filterNonMonitors() {
5282 windows.clear();
5283 portalWindows.clear();
5284}
5285
Michael Wrightd02c5b62014-02-10 15:10:22 -08005286sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
5287 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005288 const TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005289 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5290 return window.windowHandle;
5291 }
5292 }
Yi Kong9b14ac62018-07-17 13:48:38 -07005293 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005294}
5295
5296bool InputDispatcher::TouchState::isSlippery() const {
5297 // Must have exactly one foreground window.
5298 bool haveSlipperyForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005299 for (const TouchedWindow& window : windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005300 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5301 if (haveSlipperyForegroundWindow
5302 || !(window.windowHandle->getInfo()->layoutParamsFlags
5303 & InputWindowInfo::FLAG_SLIPPERY)) {
5304 return false;
5305 }
5306 haveSlipperyForegroundWindow = true;
5307 }
5308 }
5309 return haveSlipperyForegroundWindow;
5310}
5311
5312
5313// --- InputDispatcherThread ---
5314
5315InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
5316 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
5317}
5318
5319InputDispatcherThread::~InputDispatcherThread() {
5320}
5321
5322bool InputDispatcherThread::threadLoop() {
5323 mDispatcher->dispatchOnce();
5324 return true;
5325}
5326
5327} // namespace android