blob: 1eb979ef19c0a557c0892c202c0e0570630878cb [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
Michael Wright3dd60e22019-03-27 22:06:44 +000020#define LOG_NDEBUG 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
31// Log debug messages about registrations.
32#define DEBUG_REGISTRATION 0
33
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
38#define DEBUG_FOCUS 0
39
40// Log debug messages about the app switch latency optimization.
41#define DEBUG_APP_SWITCH 0
42
43// Log debug messages about hover events.
44#define DEBUG_HOVER 0
45
46#include "InputDispatcher.h"
47
Michael Wrightd02c5b62014-02-10 15:10:22 -080048#include <errno.h>
Siarhei Vishniakou443ad902019-03-06 17:25:41 -080049#include <inttypes.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080050#include <limits.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070051#include <stddef.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080052#include <time.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070053#include <unistd.h>
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -070054#include <queue>
55#include <sstream>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070056
Michael Wright2b3c3302018-03-02 17:19:13 +000057#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080058#include <android-base/stringprintf.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070059#include <log/log.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070060#include <utils/Trace.h>
61#include <powermanager/PowerManager.h>
Robert Carr4e670e52018-08-15 13:26:12 -070062#include <binder/Binder.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080063
64#define INDENT " "
65#define INDENT2 " "
66#define INDENT3 " "
67#define INDENT4 " "
68
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080069using android::base::StringPrintf;
70
Michael Wrightd02c5b62014-02-10 15:10:22 -080071namespace android {
72
73// Default input dispatching timeout if there is no focused application or paused window
74// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000075constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080076
77// Amount of time to allow for all pending events to be processed when an app switch
78// key is on the way. This is used to preempt input dispatch and drop input events
79// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000080constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080081
82// Amount of time to allow for an event to be dispatched (measured since its eventTime)
83// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000084constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080085
86// Amount of time to allow touch events to be streamed out to a connection before requiring
87// that the first event be finished. This value extends the ANR timeout by the specified
88// amount. For example, if streaming is allowed to get ahead by one second relative to the
89// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000090constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080091
92// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +000093constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
94
95// Log a warning when an interception call takes longer than this to process.
96constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -080097
98// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +000099constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
100
Prabir Pradhan42611e02018-11-27 14:04:02 -0800101// Sequence number for synthesized or injected events.
102constexpr uint32_t SYNTHESIZED_EVENT_SEQUENCE_NUM = 0;
103
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104
105static inline nsecs_t now() {
106 return systemTime(SYSTEM_TIME_MONOTONIC);
107}
108
109static inline const char* toString(bool value) {
110 return value ? "true" : "false";
111}
112
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800113static std::string motionActionToString(int32_t action) {
114 // Convert MotionEvent action to string
115 switch(action & AMOTION_EVENT_ACTION_MASK) {
116 case AMOTION_EVENT_ACTION_DOWN:
117 return "DOWN";
118 case AMOTION_EVENT_ACTION_MOVE:
119 return "MOVE";
120 case AMOTION_EVENT_ACTION_UP:
121 return "UP";
122 case AMOTION_EVENT_ACTION_POINTER_DOWN:
123 return "POINTER_DOWN";
124 case AMOTION_EVENT_ACTION_POINTER_UP:
125 return "POINTER_UP";
126 }
127 return StringPrintf("%" PRId32, action);
128}
129
130static std::string keyActionToString(int32_t action) {
131 // Convert KeyEvent action to string
Michael Wright3dd60e22019-03-27 22:06:44 +0000132 switch (action) {
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800133 case AKEY_EVENT_ACTION_DOWN:
134 return "DOWN";
135 case AKEY_EVENT_ACTION_UP:
136 return "UP";
137 case AKEY_EVENT_ACTION_MULTIPLE:
138 return "MULTIPLE";
139 }
140 return StringPrintf("%" PRId32, action);
141}
142
Michael Wright3dd60e22019-03-27 22:06:44 +0000143static std::string dispatchModeToString(int32_t dispatchMode) {
144 switch (dispatchMode) {
145 case InputTarget::FLAG_DISPATCH_AS_IS:
146 return "DISPATCH_AS_IS";
147 case InputTarget::FLAG_DISPATCH_AS_OUTSIDE:
148 return "DISPATCH_AS_OUTSIDE";
149 case InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER:
150 return "DISPATCH_AS_HOVER_ENTER";
151 case InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT:
152 return "DISPATCH_AS_HOVER_EXIT";
153 case InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT:
154 return "DISPATCH_AS_SLIPPERY_EXIT";
155 case InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER:
156 return "DISPATCH_AS_SLIPPERY_ENTER";
157 }
158 return StringPrintf("%" PRId32, dispatchMode);
159}
160
Michael Wrightd02c5b62014-02-10 15:10:22 -0800161static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
162 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
163 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
164}
165
166static bool isValidKeyAction(int32_t action) {
167 switch (action) {
168 case AKEY_EVENT_ACTION_DOWN:
169 case AKEY_EVENT_ACTION_UP:
170 return true;
171 default:
172 return false;
173 }
174}
175
176static bool validateKeyEvent(int32_t action) {
177 if (! isValidKeyAction(action)) {
178 ALOGE("Key event has invalid action code 0x%x", action);
179 return false;
180 }
181 return true;
182}
183
Michael Wright7b159c92015-05-14 14:48:03 +0100184static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185 switch (action & AMOTION_EVENT_ACTION_MASK) {
186 case AMOTION_EVENT_ACTION_DOWN:
187 case AMOTION_EVENT_ACTION_UP:
188 case AMOTION_EVENT_ACTION_CANCEL:
189 case AMOTION_EVENT_ACTION_MOVE:
190 case AMOTION_EVENT_ACTION_OUTSIDE:
191 case AMOTION_EVENT_ACTION_HOVER_ENTER:
192 case AMOTION_EVENT_ACTION_HOVER_MOVE:
193 case AMOTION_EVENT_ACTION_HOVER_EXIT:
194 case AMOTION_EVENT_ACTION_SCROLL:
195 return true;
196 case AMOTION_EVENT_ACTION_POINTER_DOWN:
197 case AMOTION_EVENT_ACTION_POINTER_UP: {
198 int32_t index = getMotionEventActionPointerIndex(action);
Dan Albert1bd2fc02016-02-02 15:11:57 -0800199 return index >= 0 && index < pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800200 }
Michael Wright7b159c92015-05-14 14:48:03 +0100201 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
202 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
203 return actionButton != 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 default:
205 return false;
206 }
207}
208
Michael Wright7b159c92015-05-14 14:48:03 +0100209static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800210 const PointerProperties* pointerProperties) {
Michael Wright7b159c92015-05-14 14:48:03 +0100211 if (! isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800212 ALOGE("Motion event has invalid action code 0x%x", action);
213 return false;
214 }
215 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000216 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217 pointerCount, MAX_POINTERS);
218 return false;
219 }
220 BitSet32 pointerIdBits;
221 for (size_t i = 0; i < pointerCount; i++) {
222 int32_t id = pointerProperties[i].id;
223 if (id < 0 || id > MAX_POINTER_ID) {
224 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
225 id, MAX_POINTER_ID);
226 return false;
227 }
228 if (pointerIdBits.hasBit(id)) {
229 ALOGE("Motion event has duplicate pointer id %d", id);
230 return false;
231 }
232 pointerIdBits.markBit(id);
233 }
234 return true;
235}
236
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800237static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800238 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800239 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800240 return;
241 }
242
243 bool first = true;
244 Region::const_iterator cur = region.begin();
245 Region::const_iterator const tail = region.end();
246 while (cur != tail) {
247 if (first) {
248 first = false;
249 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800250 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800251 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800252 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800253 cur++;
254 }
255}
256
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700257/**
258 * Find the entry in std::unordered_map by key, and return it.
259 * If the entry is not found, return a default constructed entry.
260 *
261 * Useful when the entries are vectors, since an empty vector will be returned
262 * if the entry is not found.
263 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
264 */
265template <typename T, typename U>
266static T getValueByKey(const std::unordered_map<U, T>& map, U key) {
267 auto it = map.find(key);
Tiger Huang721e26f2018-07-24 22:26:19 +0800268 return it != map.end() ? it->second : T{};
269}
270
Michael Wrightd02c5b62014-02-10 15:10:22 -0800271
272// --- InputDispatcher ---
273
Garfield Tan00f511d2019-06-12 16:55:40 -0700274InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
275 : mPolicy(policy),
276 mPendingEvent(nullptr),
277 mLastDropReason(DROP_REASON_NOT_DROPPED),
278 mAppSwitchSawKeyDown(false),
279 mAppSwitchDueTime(LONG_LONG_MAX),
280 mNextUnblockedEvent(nullptr),
281 mDispatchEnabled(false),
282 mDispatchFrozen(false),
283 mInputFilterEnabled(false),
284 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
285 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800286 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800287 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800288
Yi Kong9b14ac62018-07-17 13:48:38 -0700289 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800290
291 policy->getDispatcherConfiguration(&mConfig);
292}
293
294InputDispatcher::~InputDispatcher() {
295 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800296 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800297
298 resetKeyRepeatLocked();
299 releasePendingEventLocked();
300 drainInboundQueueLocked();
301 }
302
303 while (mConnectionsByFd.size() != 0) {
304 unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
305 }
306}
307
308void InputDispatcher::dispatchOnce() {
309 nsecs_t nextWakeupTime = LONG_LONG_MAX;
310 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800311 std::scoped_lock _l(mLock);
312 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800313
314 // Run a dispatch loop if there are no pending commands.
315 // The dispatch loop might enqueue commands to run afterwards.
316 if (!haveCommandsLocked()) {
317 dispatchOnceInnerLocked(&nextWakeupTime);
318 }
319
320 // Run all pending commands if there are any.
321 // If any commands were run then force the next poll to wake up immediately.
322 if (runCommandsLockedInterruptible()) {
323 nextWakeupTime = LONG_LONG_MIN;
324 }
325 } // release lock
326
327 // Wait for callback or timeout or wake. (make sure we round up, not down)
328 nsecs_t currentTime = now();
329 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
330 mLooper->pollOnce(timeoutMillis);
331}
332
333void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
334 nsecs_t currentTime = now();
335
Jeff Browndc5992e2014-04-11 01:27:26 -0700336 // Reset the key repeat timer whenever normal dispatch is suspended while the
337 // device is in a non-interactive state. This is to ensure that we abort a key
338 // repeat if the device is just coming out of sleep.
339 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800340 resetKeyRepeatLocked();
341 }
342
343 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
344 if (mDispatchFrozen) {
345#if DEBUG_FOCUS
346 ALOGD("Dispatch frozen. Waiting some more.");
347#endif
348 return;
349 }
350
351 // Optimize latency of app switches.
352 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
353 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
354 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
355 if (mAppSwitchDueTime < *nextWakeupTime) {
356 *nextWakeupTime = mAppSwitchDueTime;
357 }
358
359 // Ready to start a new event.
360 // If we don't already have a pending event, go grab one.
361 if (! mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700362 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800363 if (isAppSwitchDue) {
364 // The inbound queue is empty so the app switch key we were waiting
365 // for will never arrive. Stop waiting for it.
366 resetPendingAppSwitchLocked(false);
367 isAppSwitchDue = false;
368 }
369
370 // Synthesize a key repeat if appropriate.
371 if (mKeyRepeatState.lastKeyEntry) {
372 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
373 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
374 } else {
375 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
376 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
377 }
378 }
379 }
380
381 // Nothing to do if there is no pending event.
382 if (!mPendingEvent) {
383 return;
384 }
385 } else {
386 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700387 mPendingEvent = mInboundQueue.front();
388 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800389 traceInboundQueueLengthLocked();
390 }
391
392 // Poke user activity for this event.
393 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
394 pokeUserActivityLocked(mPendingEvent);
395 }
396
397 // Get ready to dispatch the event.
398 resetANRTimeoutsLocked();
399 }
400
401 // Now we have an event to dispatch.
402 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700403 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800404 bool done = false;
405 DropReason dropReason = DROP_REASON_NOT_DROPPED;
406 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
407 dropReason = DROP_REASON_POLICY;
408 } else if (!mDispatchEnabled) {
409 dropReason = DROP_REASON_DISABLED;
410 }
411
412 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700413 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800414 }
415
416 switch (mPendingEvent->type) {
417 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
418 ConfigurationChangedEntry* typedEntry =
419 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
420 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
421 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
422 break;
423 }
424
425 case EventEntry::TYPE_DEVICE_RESET: {
426 DeviceResetEntry* typedEntry =
427 static_cast<DeviceResetEntry*>(mPendingEvent);
428 done = dispatchDeviceResetLocked(currentTime, typedEntry);
429 dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
430 break;
431 }
432
433 case EventEntry::TYPE_KEY: {
434 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
435 if (isAppSwitchDue) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800436 if (isAppSwitchKeyEvent(typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800437 resetPendingAppSwitchLocked(true);
438 isAppSwitchDue = false;
439 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
440 dropReason = DROP_REASON_APP_SWITCH;
441 }
442 }
443 if (dropReason == DROP_REASON_NOT_DROPPED
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800444 && isStaleEvent(currentTime, typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800445 dropReason = DROP_REASON_STALE;
446 }
447 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
448 dropReason = DROP_REASON_BLOCKED;
449 }
450 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
451 break;
452 }
453
454 case EventEntry::TYPE_MOTION: {
455 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
456 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
457 dropReason = DROP_REASON_APP_SWITCH;
458 }
459 if (dropReason == DROP_REASON_NOT_DROPPED
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800460 && isStaleEvent(currentTime, typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800461 dropReason = DROP_REASON_STALE;
462 }
463 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
464 dropReason = DROP_REASON_BLOCKED;
465 }
466 done = dispatchMotionLocked(currentTime, typedEntry,
467 &dropReason, nextWakeupTime);
468 break;
469 }
470
471 default:
472 ALOG_ASSERT(false);
473 break;
474 }
475
476 if (done) {
477 if (dropReason != DROP_REASON_NOT_DROPPED) {
478 dropInboundEventLocked(mPendingEvent, dropReason);
479 }
Michael Wright3a981722015-06-10 15:26:13 +0100480 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800481
482 releasePendingEventLocked();
483 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
484 }
485}
486
487bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700488 bool needWake = mInboundQueue.empty();
489 mInboundQueue.push_back(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800490 traceInboundQueueLengthLocked();
491
492 switch (entry->type) {
493 case EventEntry::TYPE_KEY: {
494 // Optimize app switch latency.
495 // If the application takes too long to catch up then we drop all events preceding
496 // the app switch key.
497 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800498 if (isAppSwitchKeyEvent(keyEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800499 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
500 mAppSwitchSawKeyDown = true;
501 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
502 if (mAppSwitchSawKeyDown) {
503#if DEBUG_APP_SWITCH
504 ALOGD("App switch is pending!");
505#endif
506 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
507 mAppSwitchSawKeyDown = false;
508 needWake = true;
509 }
510 }
511 }
512 break;
513 }
514
515 case EventEntry::TYPE_MOTION: {
516 // Optimize case where the current application is unresponsive and the user
517 // decides to touch a window in a different application.
518 // If the application takes too long to catch up then we drop all events preceding
519 // the touch into the other window.
520 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
521 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
522 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
523 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
Robert Carr740167f2018-10-11 19:03:41 -0700524 && mInputTargetWaitApplicationToken != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800525 int32_t displayId = motionEntry->displayId;
526 int32_t x = int32_t(motionEntry->pointerCoords[0].
527 getAxisValue(AMOTION_EVENT_AXIS_X));
528 int32_t y = int32_t(motionEntry->pointerCoords[0].
529 getAxisValue(AMOTION_EVENT_AXIS_Y));
530 sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
Yi Kong9b14ac62018-07-17 13:48:38 -0700531 if (touchedWindowHandle != nullptr
Robert Carr740167f2018-10-11 19:03:41 -0700532 && touchedWindowHandle->getApplicationToken()
533 != mInputTargetWaitApplicationToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800534 // User touched a different application than the one we are waiting on.
535 // Flag the event, and start pruning the input queue.
536 mNextUnblockedEvent = motionEntry;
537 needWake = true;
538 }
539 }
540 break;
541 }
542 }
543
544 return needWake;
545}
546
547void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
548 entry->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700549 mRecentQueue.push_back(entry);
550 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
551 mRecentQueue.front()->release();
552 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800553 }
554}
555
556sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800557 int32_t x, int32_t y, bool addOutsideTargets, bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800558 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800559 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
560 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800561 const InputWindowInfo* windowInfo = windowHandle->getInfo();
562 if (windowInfo->displayId == displayId) {
563 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800564
565 if (windowInfo->visible) {
566 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
567 bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
568 | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
569 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800570 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
571 if (portalToDisplayId != ADISPLAY_ID_NONE
572 && portalToDisplayId != displayId) {
573 if (addPortalWindows) {
574 // For the monitoring channels of the display.
575 mTempTouchState.addPortalWindow(windowHandle);
576 }
577 return findTouchedWindowAtLocked(
578 portalToDisplayId, x, y, addOutsideTargets, addPortalWindows);
579 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800580 // Found window.
581 return windowHandle;
582 }
583 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800584
585 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
586 mTempTouchState.addOrUpdateWindow(
587 windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE, BitSet32(0));
588 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800589 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800590 }
591 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700592 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800593}
594
Michael Wright3dd60e22019-03-27 22:06:44 +0000595std::vector<InputDispatcher::TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
596 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
597 std::vector<TouchedMonitor> touchedMonitors;
598
599 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
600 addGestureMonitors(monitors, touchedMonitors);
601 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
602 const InputWindowInfo* windowInfo = portalWindow->getInfo();
603 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
604 addGestureMonitors(monitors, touchedMonitors,
605 -windowInfo->frameLeft, -windowInfo->frameTop);
606 }
607 return touchedMonitors;
608}
609
610void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
611 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset, float yOffset) {
612 if (monitors.empty()) {
613 return;
614 }
615 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
616 for (const Monitor& monitor : monitors) {
617 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
618 }
619}
620
Michael Wrightd02c5b62014-02-10 15:10:22 -0800621void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
622 const char* reason;
623 switch (dropReason) {
624 case DROP_REASON_POLICY:
625#if DEBUG_INBOUND_EVENT_DETAILS
626 ALOGD("Dropped event because policy consumed it.");
627#endif
628 reason = "inbound event was dropped because the policy consumed it";
629 break;
630 case DROP_REASON_DISABLED:
Michael Wright3a981722015-06-10 15:26:13 +0100631 if (mLastDropReason != DROP_REASON_DISABLED) {
632 ALOGI("Dropped event because input dispatch is disabled.");
633 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800634 reason = "inbound event was dropped because input dispatch is disabled";
635 break;
636 case DROP_REASON_APP_SWITCH:
637 ALOGI("Dropped event because of pending overdue app switch.");
638 reason = "inbound event was dropped because of pending overdue app switch";
639 break;
640 case DROP_REASON_BLOCKED:
641 ALOGI("Dropped event because the current application is not responding and the user "
642 "has started interacting with a different application.");
643 reason = "inbound event was dropped because the current application is not responding "
644 "and the user has started interacting with a different application";
645 break;
646 case DROP_REASON_STALE:
647 ALOGI("Dropped event because it is stale.");
648 reason = "inbound event was dropped because it is stale";
649 break;
650 default:
651 ALOG_ASSERT(false);
652 return;
653 }
654
655 switch (entry->type) {
656 case EventEntry::TYPE_KEY: {
657 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
658 synthesizeCancelationEventsForAllConnectionsLocked(options);
659 break;
660 }
661 case EventEntry::TYPE_MOTION: {
662 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
663 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
664 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
665 synthesizeCancelationEventsForAllConnectionsLocked(options);
666 } else {
667 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
668 synthesizeCancelationEventsForAllConnectionsLocked(options);
669 }
670 break;
671 }
672 }
673}
674
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800675static bool isAppSwitchKeyCode(int32_t keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800676 return keyCode == AKEYCODE_HOME
677 || keyCode == AKEYCODE_ENDCALL
678 || keyCode == AKEYCODE_APP_SWITCH;
679}
680
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800681bool InputDispatcher::isAppSwitchKeyEvent(KeyEntry* keyEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800682 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
683 && isAppSwitchKeyCode(keyEntry->keyCode)
684 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
685 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
686}
687
688bool InputDispatcher::isAppSwitchPendingLocked() {
689 return mAppSwitchDueTime != LONG_LONG_MAX;
690}
691
692void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
693 mAppSwitchDueTime = LONG_LONG_MAX;
694
695#if DEBUG_APP_SWITCH
696 if (handled) {
697 ALOGD("App switch has arrived.");
698 } else {
699 ALOGD("App switch was abandoned.");
700 }
701#endif
702}
703
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800704bool InputDispatcher::isStaleEvent(nsecs_t currentTime, EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800705 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
706}
707
708bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700709 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800710}
711
712bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700713 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800714 return false;
715 }
716
717 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700718 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700719 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800720 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700721 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800722
723 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700724 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800725 return true;
726}
727
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700728void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
729 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800730}
731
732void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700733 while (!mInboundQueue.empty()) {
734 EventEntry* entry = mInboundQueue.front();
735 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800736 releaseInboundEventLocked(entry);
737 }
738 traceInboundQueueLengthLocked();
739}
740
741void InputDispatcher::releasePendingEventLocked() {
742 if (mPendingEvent) {
743 resetANRTimeoutsLocked();
744 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700745 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800746 }
747}
748
749void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
750 InjectionState* injectionState = entry->injectionState;
751 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
752#if DEBUG_DISPATCH_CYCLE
753 ALOGD("Injected inbound event was dropped.");
754#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800755 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800756 }
757 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700758 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800759 }
760 addRecentEventLocked(entry);
761 entry->release();
762}
763
764void InputDispatcher::resetKeyRepeatLocked() {
765 if (mKeyRepeatState.lastKeyEntry) {
766 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700767 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800768 }
769}
770
771InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
772 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
773
774 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700775 uint32_t policyFlags = entry->policyFlags &
776 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800777 if (entry->refCount == 1) {
778 entry->recycle();
779 entry->eventTime = currentTime;
780 entry->policyFlags = policyFlags;
781 entry->repeatCount += 1;
782 } else {
Prabir Pradhan42611e02018-11-27 14:04:02 -0800783 KeyEntry* newEntry = new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100784 entry->deviceId, entry->source, entry->displayId, policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800785 entry->action, entry->flags, entry->keyCode, entry->scanCode,
786 entry->metaState, entry->repeatCount + 1, entry->downTime);
787
788 mKeyRepeatState.lastKeyEntry = newEntry;
789 entry->release();
790
791 entry = newEntry;
792 }
793 entry->syntheticRepeat = true;
794
795 // Increment reference count since we keep a reference to the event in
796 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
797 entry->refCount += 1;
798
799 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
800 return entry;
801}
802
803bool InputDispatcher::dispatchConfigurationChangedLocked(
804 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
805#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700806 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800807#endif
808
809 // Reset key repeating in case a keyboard device was added or removed or something.
810 resetKeyRepeatLocked();
811
812 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700813 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
814 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800815 commandEntry->eventTime = entry->eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700816 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800817 return true;
818}
819
820bool InputDispatcher::dispatchDeviceResetLocked(
821 nsecs_t currentTime, DeviceResetEntry* entry) {
822#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700823 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
824 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800825#endif
826
827 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
828 "device was reset");
829 options.deviceId = entry->deviceId;
830 synthesizeCancelationEventsForAllConnectionsLocked(options);
831 return true;
832}
833
834bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
835 DropReason* dropReason, nsecs_t* nextWakeupTime) {
836 // Preprocessing.
837 if (! entry->dispatchInProgress) {
838 if (entry->repeatCount == 0
839 && entry->action == AKEY_EVENT_ACTION_DOWN
840 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
841 && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
842 if (mKeyRepeatState.lastKeyEntry
843 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
844 // We have seen two identical key downs in a row which indicates that the device
845 // driver is automatically generating key repeats itself. We take note of the
846 // repeat here, but we disable our own next key repeat timer since it is clear that
847 // we will not need to synthesize key repeats ourselves.
848 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
849 resetKeyRepeatLocked();
850 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
851 } else {
852 // Not a repeat. Save key down state in case we do see a repeat later.
853 resetKeyRepeatLocked();
854 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
855 }
856 mKeyRepeatState.lastKeyEntry = entry;
857 entry->refCount += 1;
858 } else if (! entry->syntheticRepeat) {
859 resetKeyRepeatLocked();
860 }
861
862 if (entry->repeatCount == 1) {
863 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
864 } else {
865 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
866 }
867
868 entry->dispatchInProgress = true;
869
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800870 logOutboundKeyDetails("dispatchKey - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800871 }
872
873 // Handle case where the policy asked us to try again later last time.
874 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
875 if (currentTime < entry->interceptKeyWakeupTime) {
876 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
877 *nextWakeupTime = entry->interceptKeyWakeupTime;
878 }
879 return false; // wait until next wakeup
880 }
881 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
882 entry->interceptKeyWakeupTime = 0;
883 }
884
885 // Give the policy a chance to intercept the key.
886 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
887 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700888 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700889 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +0800890 sp<InputWindowHandle> focusedWindowHandle =
891 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(entry));
892 if (focusedWindowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -0700893 commandEntry->inputChannel =
894 getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800895 }
896 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700897 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800898 entry->refCount += 1;
899 return false; // wait for the command to run
900 } else {
901 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
902 }
903 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
904 if (*dropReason == DROP_REASON_NOT_DROPPED) {
905 *dropReason = DROP_REASON_POLICY;
906 }
907 }
908
909 // Clean up if dropping the event.
910 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800911 setInjectionResult(entry, *dropReason == DROP_REASON_POLICY
Michael Wrightd02c5b62014-02-10 15:10:22 -0800912 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800913 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800914 return true;
915 }
916
917 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800918 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800919 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
920 entry, inputTargets, nextWakeupTime);
921 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
922 return false;
923 }
924
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800925 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800926 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
927 return true;
928 }
929
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800930 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +0000931 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800932
933 // Dispatch the key.
934 dispatchEventLocked(currentTime, entry, inputTargets);
935 return true;
936}
937
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800938void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800939#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100940 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
941 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +0800942 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800943 prefix,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100944 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800945 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Arthur Hung82a4cad2018-11-15 12:10:30 +0800946 entry->repeatCount, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800947#endif
948}
949
950bool InputDispatcher::dispatchMotionLocked(
951 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000952 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800953 // Preprocessing.
954 if (! entry->dispatchInProgress) {
955 entry->dispatchInProgress = true;
956
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800957 logOutboundMotionDetails("dispatchMotion - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800958 }
959
960 // Clean up if dropping the event.
961 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800962 setInjectionResult(entry, *dropReason == DROP_REASON_POLICY
Michael Wrightd02c5b62014-02-10 15:10:22 -0800963 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
964 return true;
965 }
966
967 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
968
969 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800970 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800971
972 bool conflictingPointerActions = false;
973 int32_t injectionResult;
974 if (isPointerEvent) {
975 // Pointer event. (eg. touchscreen)
976 injectionResult = findTouchedWindowTargetsLocked(currentTime,
977 entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
978 } else {
979 // Non touch event. (eg. trackball)
980 injectionResult = findFocusedWindowTargetsLocked(currentTime,
981 entry, inputTargets, nextWakeupTime);
982 }
983 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
984 return false;
985 }
986
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800987 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800988 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +0100989 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
990 CancelationOptions::Mode mode(isPointerEvent ?
991 CancelationOptions::CANCEL_POINTER_EVENTS :
992 CancelationOptions::CANCEL_NON_POINTER_EVENTS);
993 CancelationOptions options(mode, "input event injection failed");
994 synthesizeCancelationEventsForMonitorsLocked(options);
995 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800996 return true;
997 }
998
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800999 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +00001000 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001001
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001002 if (isPointerEvent) {
1003 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1004 if (stateIndex >= 0) {
1005 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001006 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001007 // The event has gone through these portal windows, so we add monitoring targets of
1008 // the corresponding displays as well.
1009 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001010 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001011 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001012 -windowInfo->frameLeft, -windowInfo->frameTop);
1013 }
1014 }
1015 }
1016 }
1017
Michael Wrightd02c5b62014-02-10 15:10:22 -08001018 // Dispatch the motion.
1019 if (conflictingPointerActions) {
1020 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
1021 "conflicting pointer actions");
1022 synthesizeCancelationEventsForAllConnectionsLocked(options);
1023 }
1024 dispatchEventLocked(currentTime, entry, inputTargets);
1025 return true;
1026}
1027
1028
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001029void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001030#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001031 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1032 ", policyFlags=0x%x, "
Michael Wright7b159c92015-05-14 14:48:03 +01001033 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1034 "metaState=0x%x, buttonState=0x%x,"
Arthur Hung82a4cad2018-11-15 12:10:30 +08001035 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001036 prefix,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001037 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001038 entry->action, entry->actionButton, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001039 entry->metaState, entry->buttonState,
1040 entry->edgeFlags, entry->xPrecision, entry->yPrecision,
Arthur Hung82a4cad2018-11-15 12:10:30 +08001041 entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001042
1043 for (uint32_t i = 0; i < entry->pointerCount; i++) {
1044 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1045 "x=%f, y=%f, pressure=%f, size=%f, "
1046 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001047 "orientation=%f",
Michael Wrightd02c5b62014-02-10 15:10:22 -08001048 i, entry->pointerProperties[i].id,
1049 entry->pointerProperties[i].toolType,
1050 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1051 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1052 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1053 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1054 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1055 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1056 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1057 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001058 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001059 }
1060#endif
1061}
1062
1063void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001064 EventEntry* eventEntry, const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001065 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001066#if DEBUG_DISPATCH_CYCLE
1067 ALOGD("dispatchEventToCurrentInputTargets");
1068#endif
1069
1070 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1071
1072 pokeUserActivityLocked(eventEntry);
1073
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001074 for (const InputTarget& inputTarget : inputTargets) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001075 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
1076 if (connectionIndex >= 0) {
1077 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1078 prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
1079 } else {
1080#if DEBUG_FOCUS
1081 ALOGD("Dropping event delivery to target with channel '%s' because it "
1082 "is no longer registered with the input dispatcher.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001083 inputTarget.inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001084#endif
1085 }
1086 }
1087}
1088
1089int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
1090 const EventEntry* entry,
1091 const sp<InputApplicationHandle>& applicationHandle,
1092 const sp<InputWindowHandle>& windowHandle,
1093 nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001094 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001095 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
1096#if DEBUG_FOCUS
1097 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1098#endif
1099 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1100 mInputTargetWaitStartTime = currentTime;
1101 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1102 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001103 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001104 }
1105 } else {
1106 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1107#if DEBUG_FOCUS
1108 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001109 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001110 reason);
1111#endif
1112 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001113 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001114 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001115 } else if (applicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001116 timeout = applicationHandle->getDispatchingTimeout(
1117 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1118 } else {
1119 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1120 }
1121
1122 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1123 mInputTargetWaitStartTime = currentTime;
1124 mInputTargetWaitTimeoutTime = currentTime + timeout;
1125 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001126 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001127
Yi Kong9b14ac62018-07-17 13:48:38 -07001128 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001129 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130 }
Robert Carr740167f2018-10-11 19:03:41 -07001131 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1132 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001133 }
1134 }
1135 }
1136
1137 if (mInputTargetWaitTimeoutExpired) {
1138 return INPUT_EVENT_INJECTION_TIMED_OUT;
1139 }
1140
1141 if (currentTime >= mInputTargetWaitTimeoutTime) {
1142 onANRLocked(currentTime, applicationHandle, windowHandle,
1143 entry->eventTime, mInputTargetWaitStartTime, reason);
1144
1145 // Force poll loop to wake up immediately on next iteration once we get the
1146 // ANR response back from the policy.
1147 *nextWakeupTime = LONG_LONG_MIN;
1148 return INPUT_EVENT_INJECTION_PENDING;
1149 } else {
1150 // Force poll loop to wake up when timeout is due.
1151 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1152 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1153 }
1154 return INPUT_EVENT_INJECTION_PENDING;
1155 }
1156}
1157
Robert Carr803535b2018-08-02 16:38:15 -07001158void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1159 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1160 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1161 state.removeWindowByToken(token);
1162 }
1163}
1164
Michael Wrightd02c5b62014-02-10 15:10:22 -08001165void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1166 const sp<InputChannel>& inputChannel) {
1167 if (newTimeout > 0) {
1168 // Extend the timeout.
1169 mInputTargetWaitTimeoutTime = now() + newTimeout;
1170 } else {
1171 // Give up.
1172 mInputTargetWaitTimeoutExpired = true;
1173
1174 // Input state will not be realistic. Mark it out of sync.
1175 if (inputChannel.get()) {
1176 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1177 if (connectionIndex >= 0) {
1178 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
Robert Carr803535b2018-08-02 16:38:15 -07001179 sp<IBinder> token = connection->inputChannel->getToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001180
Robert Carr803535b2018-08-02 16:38:15 -07001181 if (token != nullptr) {
1182 removeWindowByTokenLocked(token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001183 }
1184
1185 if (connection->status == Connection::STATUS_NORMAL) {
1186 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1187 "application not responding");
1188 synthesizeCancelationEventsForConnectionLocked(connection, options);
1189 }
1190 }
1191 }
1192 }
1193}
1194
1195nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
1196 nsecs_t currentTime) {
1197 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1198 return currentTime - mInputTargetWaitStartTime;
1199 }
1200 return 0;
1201}
1202
1203void InputDispatcher::resetANRTimeoutsLocked() {
1204#if DEBUG_FOCUS
1205 ALOGD("Resetting ANR timeouts.");
1206#endif
1207
1208 // Reset input target wait timeout.
1209 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001210 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001211}
1212
Tiger Huang721e26f2018-07-24 22:26:19 +08001213/**
1214 * Get the display id that the given event should go to. If this event specifies a valid display id,
1215 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1216 * Focused display is the display that the user most recently interacted with.
1217 */
1218int32_t InputDispatcher::getTargetDisplayId(const EventEntry* entry) {
1219 int32_t displayId;
1220 switch (entry->type) {
1221 case EventEntry::TYPE_KEY: {
1222 const KeyEntry* typedEntry = static_cast<const KeyEntry*>(entry);
1223 displayId = typedEntry->displayId;
1224 break;
1225 }
1226 case EventEntry::TYPE_MOTION: {
1227 const MotionEntry* typedEntry = static_cast<const MotionEntry*>(entry);
1228 displayId = typedEntry->displayId;
1229 break;
1230 }
1231 default: {
1232 ALOGE("Unsupported event type '%" PRId32 "' for target display.", entry->type);
1233 return ADISPLAY_ID_NONE;
1234 }
1235 }
1236 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1237}
1238
Michael Wrightd02c5b62014-02-10 15:10:22 -08001239int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001240 const EventEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001241 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001242 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001243
Tiger Huang721e26f2018-07-24 22:26:19 +08001244 int32_t displayId = getTargetDisplayId(entry);
1245 sp<InputWindowHandle> focusedWindowHandle =
1246 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1247 sp<InputApplicationHandle> focusedApplicationHandle =
1248 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1249
Michael Wrightd02c5b62014-02-10 15:10:22 -08001250 // If there is no currently focused window and no focused application
1251 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001252 if (focusedWindowHandle == nullptr) {
1253 if (focusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001254 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001255 focusedApplicationHandle, nullptr, nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001256 "Waiting because no window has focus but there is a "
1257 "focused application that may eventually add a window "
1258 "when it finishes starting up.");
1259 goto Unresponsive;
1260 }
1261
Arthur Hung3b413f22018-10-26 18:05:34 +08001262 ALOGI("Dropping event because there is no focused window or focused application in display "
1263 "%" PRId32 ".", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001264 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1265 goto Failed;
1266 }
1267
1268 // Check permissions.
Tiger Huang721e26f2018-07-24 22:26:19 +08001269 if (!checkInjectionPermission(focusedWindowHandle, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001270 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1271 goto Failed;
1272 }
1273
Jeff Brownffb49772014-10-10 19:01:34 -07001274 // Check whether the window is ready for more input.
1275 reason = checkWindowReadyForMoreInputLocked(currentTime,
Tiger Huang721e26f2018-07-24 22:26:19 +08001276 focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001277 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001278 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001279 focusedApplicationHandle, focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001280 goto Unresponsive;
1281 }
1282
1283 // Success! Output targets.
1284 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001285 addWindowTargetLocked(focusedWindowHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001286 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
1287 inputTargets);
1288
1289 // Done.
1290Failed:
1291Unresponsive:
1292 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001293 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001294#if DEBUG_FOCUS
1295 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1296 "timeSpentWaitingForApplication=%0.1fms",
1297 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1298#endif
1299 return injectionResult;
1300}
1301
1302int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001303 const MotionEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001304 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001305 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001306 enum InjectionPermission {
1307 INJECTION_PERMISSION_UNKNOWN,
1308 INJECTION_PERMISSION_GRANTED,
1309 INJECTION_PERMISSION_DENIED
1310 };
1311
Michael Wrightd02c5b62014-02-10 15:10:22 -08001312 // For security reasons, we defer updating the touch state until we are sure that
1313 // event injection will be allowed.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001314 int32_t displayId = entry->displayId;
1315 int32_t action = entry->action;
1316 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1317
1318 // Update the touch state as needed based on the properties of the touch event.
1319 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1320 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1321 sp<InputWindowHandle> newHoverWindowHandle;
1322
Jeff Brownf086ddb2014-02-11 14:28:48 -08001323 // Copy current touch state into mTempTouchState.
1324 // This state is always reset at the end of this function, so if we don't find state
1325 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001326 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001327 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1328 if (oldStateIndex >= 0) {
1329 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1330 mTempTouchState.copyFrom(*oldState);
1331 }
1332
1333 bool isSplit = mTempTouchState.split;
1334 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0
1335 && (mTempTouchState.deviceId != entry->deviceId
1336 || mTempTouchState.source != entry->source
1337 || mTempTouchState.displayId != displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001338 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1339 || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1340 || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1341 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
1342 || maskedAction == AMOTION_EVENT_ACTION_SCROLL
1343 || isHoverAction);
Garfield Tan00f511d2019-06-12 16:55:40 -07001344 const bool isFromMouse = entry->source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001345 bool wrongDevice = false;
1346 if (newGesture) {
1347 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001348 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001349#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001350 ALOGD("Dropping event because a pointer for a different device is already down "
1351 "in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001352#endif
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001353 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001354 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1355 switchedDevice = false;
1356 wrongDevice = true;
1357 goto Failed;
1358 }
1359 mTempTouchState.reset();
1360 mTempTouchState.down = down;
1361 mTempTouchState.deviceId = entry->deviceId;
1362 mTempTouchState.source = entry->source;
1363 mTempTouchState.displayId = displayId;
1364 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001365 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
1366#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001367 ALOGI("Dropping move event because a pointer for a different device is already active "
1368 "in display %" PRId32, displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001369#endif
1370 // TODO: test multiple simultaneous input streams.
1371 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1372 switchedDevice = false;
1373 wrongDevice = true;
1374 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001375 }
1376
1377 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1378 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1379
Garfield Tan00f511d2019-06-12 16:55:40 -07001380 int32_t x;
1381 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001382 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001383 // Always dispatch mouse events to cursor position.
1384 if (isFromMouse) {
1385 x = int32_t(entry->xCursorPosition);
1386 y = int32_t(entry->yCursorPosition);
1387 } else {
1388 x = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1389 y = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
1390 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001391 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001392 sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +00001393 displayId, x, y, isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
1394
1395 std::vector<TouchedMonitor> newGestureMonitors = isDown
1396 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1397 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001398
Michael Wrightd02c5b62014-02-10 15:10:22 -08001399 // Figure out whether splitting will be allowed for this window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001400 if (newTouchedWindowHandle != nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001401 && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001402 // New window supports splitting, but we should never split mouse events.
1403 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001404 } else if (isSplit) {
1405 // New window does not support splitting but we have already split events.
1406 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001407 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001408 }
1409
1410 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001411 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001412 // Try to assign the pointer to the first foreground window we find, if there is one.
1413 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001414 }
1415
1416 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1417 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
1418 "(%d, %d) in display %" PRId32 ".", x, y, displayId);
1419 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1420 goto Failed;
1421 }
1422
1423 if (newTouchedWindowHandle != nullptr) {
1424 // Set target flags.
1425 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1426 if (isSplit) {
1427 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001428 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001429 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1430 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1431 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1432 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1433 }
1434
1435 // Update hover state.
1436 if (isHoverAction) {
1437 newHoverWindowHandle = newTouchedWindowHandle;
1438 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1439 newHoverWindowHandle = mLastHoverWindowHandle;
1440 }
1441
1442 // Update the temporary touch state.
1443 BitSet32 pointerIds;
1444 if (isSplit) {
1445 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1446 pointerIds.markBit(pointerId);
1447 }
1448 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001449 }
1450
Michael Wright3dd60e22019-03-27 22:06:44 +00001451 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001452 } else {
1453 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1454
1455 // If the pointer is not currently down, then ignore the event.
1456 if (! mTempTouchState.down) {
1457#if DEBUG_FOCUS
1458 ALOGD("Dropping event because the pointer is not down or we previously "
Arthur Hung3b413f22018-10-26 18:05:34 +08001459 "dropped the pointer down event in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001460#endif
1461 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1462 goto Failed;
1463 }
1464
1465 // Check whether touches should slip outside of the current foreground window.
1466 if (maskedAction == AMOTION_EVENT_ACTION_MOVE
1467 && entry->pointerCount == 1
1468 && mTempTouchState.isSlippery()) {
1469 int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1470 int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
1471
1472 sp<InputWindowHandle> oldTouchedWindowHandle =
1473 mTempTouchState.getFirstForegroundWindowHandle();
1474 sp<InputWindowHandle> newTouchedWindowHandle =
1475 findTouchedWindowAtLocked(displayId, x, y);
1476 if (oldTouchedWindowHandle != newTouchedWindowHandle
Michael Wright3dd60e22019-03-27 22:06:44 +00001477 && oldTouchedWindowHandle != nullptr
Yi Kong9b14ac62018-07-17 13:48:38 -07001478 && newTouchedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001479#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001480 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001481 oldTouchedWindowHandle->getName().c_str(),
Arthur Hung3b413f22018-10-26 18:05:34 +08001482 newTouchedWindowHandle->getName().c_str(),
1483 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001484#endif
1485 // Make a slippery exit from the old window.
1486 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1487 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
1488
1489 // Make a slippery entrance into the new window.
1490 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1491 isSplit = true;
1492 }
1493
1494 int32_t targetFlags = InputTarget::FLAG_FOREGROUND
1495 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
1496 if (isSplit) {
1497 targetFlags |= InputTarget::FLAG_SPLIT;
1498 }
1499 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1500 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1501 }
1502
1503 BitSet32 pointerIds;
1504 if (isSplit) {
1505 pointerIds.markBit(entry->pointerProperties[0].id);
1506 }
1507 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1508 }
1509 }
1510 }
1511
1512 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1513 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001514 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001515#if DEBUG_HOVER
1516 ALOGD("Sending hover exit event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001517 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001518#endif
1519 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1520 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
1521 }
1522
1523 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001524 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001525#if DEBUG_HOVER
1526 ALOGD("Sending hover enter event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001527 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001528#endif
1529 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1530 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
1531 }
1532 }
1533
1534 // Check permission to inject into all touched foreground windows and ensure there
1535 // is at least one touched foreground window.
1536 {
1537 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001538 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001539 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1540 haveForegroundWindow = true;
1541 if (! checkInjectionPermission(touchedWindow.windowHandle,
1542 entry->injectionState)) {
1543 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1544 injectionPermission = INJECTION_PERMISSION_DENIED;
1545 goto Failed;
1546 }
1547 }
1548 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001549 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1550 if (!haveForegroundWindow && !hasGestureMonitor) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001551#if DEBUG_FOCUS
Michael Wright3dd60e22019-03-27 22:06:44 +00001552 ALOGD("Dropping event because there is no touched foreground window in display %"
1553 PRId32 " or gesture monitor to receive it.", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001554#endif
1555 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1556 goto Failed;
1557 }
1558
1559 // Permission granted to injection into all touched foreground windows.
1560 injectionPermission = INJECTION_PERMISSION_GRANTED;
1561 }
1562
1563 // Check whether windows listening for outside touches are owned by the same UID. If it is
1564 // set the policy flag that we will not reveal coordinate information to this window.
1565 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1566 sp<InputWindowHandle> foregroundWindowHandle =
1567 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001568 if (foregroundWindowHandle) {
1569 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1570 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1571 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1572 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1573 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1574 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
1575 InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
1576 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001577 }
1578 }
1579 }
1580 }
1581
1582 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001583 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001584 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001585 // Check whether the window is ready for more input.
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001586 std::string reason = checkWindowReadyForMoreInputLocked(currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001587 touchedWindow.windowHandle, entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001588 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001589 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Yi Kong9b14ac62018-07-17 13:48:38 -07001590 nullptr, touchedWindow.windowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001591 goto Unresponsive;
1592 }
1593 }
1594 }
1595
1596 // If this is the first pointer going down and the touched window has a wallpaper
1597 // then also add the touched wallpaper windows so they are locked in for the duration
1598 // of the touch gesture.
1599 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1600 // engine only supports touch events. We would need to add a mechanism similar
1601 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1602 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1603 sp<InputWindowHandle> foregroundWindowHandle =
1604 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001605 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001606 const std::vector<sp<InputWindowHandle>> windowHandles =
1607 getWindowHandlesLocked(displayId);
1608 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001609 const InputWindowInfo* info = windowHandle->getInfo();
1610 if (info->displayId == displayId
1611 && windowHandle->getInfo()->layoutParamsType
1612 == InputWindowInfo::TYPE_WALLPAPER) {
1613 mTempTouchState.addOrUpdateWindow(windowHandle,
1614 InputTarget::FLAG_WINDOW_IS_OBSCURED
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001615 | InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED
Michael Wrightd02c5b62014-02-10 15:10:22 -08001616 | InputTarget::FLAG_DISPATCH_AS_IS,
1617 BitSet32(0));
1618 }
1619 }
1620 }
1621 }
1622
1623 // Success! Output targets.
1624 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1625
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001626 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001627 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
1628 touchedWindow.pointerIds, inputTargets);
1629 }
1630
Michael Wright3dd60e22019-03-27 22:06:44 +00001631 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1632 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
1633 touchedMonitor.yOffset, inputTargets);
1634 }
1635
Michael Wrightd02c5b62014-02-10 15:10:22 -08001636 // Drop the outside or hover touch windows since we will not care about them
1637 // in the next iteration.
1638 mTempTouchState.filterNonAsIsTouchWindows();
1639
1640Failed:
1641 // Check injection permission once and for all.
1642 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001643 if (checkInjectionPermission(nullptr, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001644 injectionPermission = INJECTION_PERMISSION_GRANTED;
1645 } else {
1646 injectionPermission = INJECTION_PERMISSION_DENIED;
1647 }
1648 }
1649
1650 // Update final pieces of touch state if the injector had permission.
1651 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1652 if (!wrongDevice) {
1653 if (switchedDevice) {
1654#if DEBUG_FOCUS
1655 ALOGD("Conflicting pointer actions: Switched to a different device.");
1656#endif
1657 *outConflictingPointerActions = true;
1658 }
1659
1660 if (isHoverAction) {
1661 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001662 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001663#if DEBUG_FOCUS
1664 ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
1665#endif
1666 *outConflictingPointerActions = true;
1667 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001668 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001669 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1670 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08001671 mTempTouchState.deviceId = entry->deviceId;
1672 mTempTouchState.source = entry->source;
1673 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001674 }
1675 } else if (maskedAction == AMOTION_EVENT_ACTION_UP
1676 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1677 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001678 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001679 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1680 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001681 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001682#if DEBUG_FOCUS
1683 ALOGD("Conflicting pointer actions: Down received while already down.");
1684#endif
1685 *outConflictingPointerActions = true;
1686 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001687 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1688 // One pointer went up.
1689 if (isSplit) {
1690 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1691 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1692
1693 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001694 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001695 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1696 touchedWindow.pointerIds.clearBit(pointerId);
1697 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001698 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001699 continue;
1700 }
1701 }
1702 i += 1;
1703 }
1704 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001705 }
1706
1707 // Save changes unless the action was scroll in which case the temporary touch
1708 // state was only valid for this one action.
1709 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1710 if (mTempTouchState.displayId >= 0) {
1711 if (oldStateIndex >= 0) {
1712 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1713 } else {
1714 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1715 }
1716 } else if (oldStateIndex >= 0) {
1717 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1718 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001719 }
1720
1721 // Update hover state.
1722 mLastHoverWindowHandle = newHoverWindowHandle;
1723 }
1724 } else {
1725#if DEBUG_FOCUS
1726 ALOGD("Not updating touch focus because injection was denied.");
1727#endif
1728 }
1729
1730Unresponsive:
1731 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1732 mTempTouchState.reset();
1733
1734 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001735 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001736#if DEBUG_FOCUS
1737 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1738 "timeSpentWaitingForApplication=%0.1fms",
1739 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1740#endif
1741 return injectionResult;
1742}
1743
1744void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001745 int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets) {
Arthur Hungceeb5d72018-12-05 16:14:18 +08001746 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1747 if (inputChannel == nullptr) {
1748 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1749 return;
1750 }
1751
Michael Wrightd02c5b62014-02-10 15:10:22 -08001752 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001753 InputTarget target;
Arthur Hungceeb5d72018-12-05 16:14:18 +08001754 target.inputChannel = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001755 target.flags = targetFlags;
1756 target.xOffset = - windowInfo->frameLeft;
1757 target.yOffset = - windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08001758 target.globalScaleFactor = windowInfo->globalScaleFactor;
1759 target.windowXScale = windowInfo->windowXScale;
1760 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001761 target.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001762 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001763}
1764
Michael Wright3dd60e22019-03-27 22:06:44 +00001765void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
1766 int32_t displayId, float xOffset, float yOffset) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001767
Michael Wright3dd60e22019-03-27 22:06:44 +00001768 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1769 mGlobalMonitorsByDisplay.find(displayId);
1770
1771 if (it != mGlobalMonitorsByDisplay.end()) {
1772 const std::vector<Monitor>& monitors = it->second;
1773 for (const Monitor& monitor : monitors) {
1774 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001775 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001776 }
1777}
1778
Michael Wright3dd60e22019-03-27 22:06:44 +00001779void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor,
1780 float xOffset, float yOffset, std::vector<InputTarget>& inputTargets) {
1781 InputTarget target;
1782 target.inputChannel = monitor.inputChannel;
1783 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1784 target.xOffset = xOffset;
1785 target.yOffset = yOffset;
1786 target.pointerIds.clear();
1787 target.globalScaleFactor = 1.0f;
1788 inputTargets.push_back(target);
1789}
1790
Michael Wrightd02c5b62014-02-10 15:10:22 -08001791bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
1792 const InjectionState* injectionState) {
1793 if (injectionState
Yi Kong9b14ac62018-07-17 13:48:38 -07001794 && (windowHandle == nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001795 || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
1796 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001797 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001798 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
1799 "owned by uid %d",
1800 injectionState->injectorPid, injectionState->injectorUid,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001801 windowHandle->getName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001802 windowHandle->getInfo()->ownerUid);
1803 } else {
1804 ALOGW("Permission denied: injecting event from pid %d uid %d",
1805 injectionState->injectorPid, injectionState->injectorUid);
1806 }
1807 return false;
1808 }
1809 return true;
1810}
1811
1812bool InputDispatcher::isWindowObscuredAtPointLocked(
1813 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
1814 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001815 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1816 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001817 if (otherHandle == windowHandle) {
1818 break;
1819 }
1820
1821 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1822 if (otherInfo->displayId == displayId
1823 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1824 && otherInfo->frameContainsPoint(x, y)) {
1825 return true;
1826 }
1827 }
1828 return false;
1829}
1830
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001831
1832bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1833 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001834 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001835 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001836 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001837 if (otherHandle == windowHandle) {
1838 break;
1839 }
1840
1841 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1842 if (otherInfo->displayId == displayId
1843 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1844 && otherInfo->overlaps(windowInfo)) {
1845 return true;
1846 }
1847 }
1848 return false;
1849}
1850
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001851std::string InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001852 const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry,
1853 const char* targetType) {
1854 // If the window is paused then keep waiting.
1855 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001856 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001857 }
1858
1859 // If the window's connection is not registered then keep waiting.
Robert Carr5c8a0262018-10-03 16:30:44 -07001860 ssize_t connectionIndex = getConnectionIndexLocked(
1861 getInputChannelLocked(windowHandle->getToken()));
Jeff Brownffb49772014-10-10 19:01:34 -07001862 if (connectionIndex < 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001863 return StringPrintf("Waiting because the %s window's input channel is not "
Jeff Brownffb49772014-10-10 19:01:34 -07001864 "registered with the input dispatcher. The window may be in the process "
1865 "of being removed.", targetType);
1866 }
1867
1868 // If the connection is dead then keep waiting.
1869 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1870 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001871 return StringPrintf("Waiting because the %s window's input connection is %s."
Jeff Brownffb49772014-10-10 19:01:34 -07001872 "The window may be in the process of being removed.", targetType,
1873 connection->getStatusLabel());
1874 }
1875
1876 // If the connection is backed up then keep waiting.
1877 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001878 return StringPrintf("Waiting because the %s window's input channel is full. "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001879 "Outbound queue length: %zu. Wait queue length: %zu.",
1880 targetType, connection->outboundQueue.size(),
1881 connection->waitQueue.size());
Jeff Brownffb49772014-10-10 19:01:34 -07001882 }
1883
1884 // Ensure that the dispatch queues aren't too far backed up for this event.
1885 if (eventEntry->type == EventEntry::TYPE_KEY) {
1886 // If the event is a key event, then we must wait for all previous events to
1887 // complete before delivering it because previous events may have the
1888 // side-effect of transferring focus to a different window and we want to
1889 // ensure that the following keys are sent to the new window.
1890 //
1891 // Suppose the user touches a button in a window then immediately presses "A".
1892 // If the button causes a pop-up window to appear then we want to ensure that
1893 // the "A" key is delivered to the new pop-up window. This is because users
1894 // often anticipate pending UI changes when typing on a keyboard.
1895 // To obtain this behavior, we must serialize key events with respect to all
1896 // prior input events.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001897 if (!connection->outboundQueue.empty() || !connection->waitQueue.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001898 return StringPrintf("Waiting to send key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001899 "finished processing all of the input events that were previously "
1900 "delivered to it. Outbound queue length: %zu. Wait queue length: "
1901 "%zu.",
1902 targetType, connection->outboundQueue.size(),
1903 connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001904 }
Jeff Brownffb49772014-10-10 19:01:34 -07001905 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001906 // Touch events can always be sent to a window immediately because the user intended
1907 // to touch whatever was visible at the time. Even if focus changes or a new
1908 // window appears moments later, the touch event was meant to be delivered to
1909 // whatever window happened to be on screen at the time.
1910 //
1911 // Generic motion events, such as trackball or joystick events are a little trickier.
1912 // Like key events, generic motion events are delivered to the focused window.
1913 // Unlike key events, generic motion events don't tend to transfer focus to other
1914 // windows and it is not important for them to be serialized. So we prefer to deliver
1915 // generic motion events as soon as possible to improve efficiency and reduce lag
1916 // through batching.
1917 //
1918 // The one case where we pause input event delivery is when the wait queue is piling
1919 // up with lots of events because the application is not responding.
1920 // This condition ensures that ANRs are detected reliably.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001921 if (!connection->waitQueue.empty() &&
1922 currentTime >=
1923 connection->waitQueue.front()->deliveryTime + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001924 return StringPrintf("Waiting to send non-key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001925 "finished processing certain input events that were delivered to "
1926 "it over "
1927 "%0.1fms ago. Wait queue length: %zu. Wait queue head age: "
1928 "%0.1fms.",
1929 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
1930 connection->waitQueue.size(),
1931 (currentTime - connection->waitQueue.front()->deliveryTime) *
1932 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001933 }
1934 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001935 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001936}
1937
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001938std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08001939 const sp<InputApplicationHandle>& applicationHandle,
1940 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001941 if (applicationHandle != nullptr) {
1942 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001943 std::string label(applicationHandle->getName());
1944 label += " - ";
1945 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001946 return label;
1947 } else {
1948 return applicationHandle->getName();
1949 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001950 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001951 return windowHandle->getName();
1952 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001953 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001954 }
1955}
1956
1957void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001958 int32_t displayId = getTargetDisplayId(eventEntry);
1959 sp<InputWindowHandle> focusedWindowHandle =
1960 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1961 if (focusedWindowHandle != nullptr) {
1962 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001963 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
1964#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001965 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001966#endif
1967 return;
1968 }
1969 }
1970
1971 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
1972 switch (eventEntry->type) {
1973 case EventEntry::TYPE_MOTION: {
1974 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1975 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1976 return;
1977 }
1978
1979 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
1980 eventType = USER_ACTIVITY_EVENT_TOUCH;
1981 }
1982 break;
1983 }
1984 case EventEntry::TYPE_KEY: {
1985 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1986 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1987 return;
1988 }
1989 eventType = USER_ACTIVITY_EVENT_BUTTON;
1990 break;
1991 }
1992 }
1993
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001994 std::unique_ptr<CommandEntry> commandEntry =
1995 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001996 commandEntry->eventTime = eventEntry->eventTime;
1997 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001998 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001999}
2000
2001void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
2002 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002003 if (ATRACE_ENABLED()) {
2004 std::string message = StringPrintf(
2005 "prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2006 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
2007 ATRACE_NAME(message.c_str());
2008 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002009#if DEBUG_DISPATCH_CYCLE
2010 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Robert Carre07e1032018-11-26 12:55:53 -08002011 "xOffset=%f, yOffset=%f, globalScaleFactor=%f, "
2012 "windowScaleFactor=(%f, %f), pointerIds=0x%x",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002013 connection->getInputChannelName().c_str(), inputTarget->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002014 inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08002015 inputTarget->globalScaleFactor,
2016 inputTarget->windowXScale, inputTarget->windowYScale,
2017 inputTarget->pointerIds.value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002018#endif
2019
2020 // Skip this event if the connection status is not normal.
2021 // We don't want to enqueue additional outbound events if the connection is broken.
2022 if (connection->status != Connection::STATUS_NORMAL) {
2023#if DEBUG_DISPATCH_CYCLE
2024 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002025 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002026#endif
2027 return;
2028 }
2029
2030 // Split a motion event if needed.
2031 if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
2032 ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
2033
2034 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
2035 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
2036 MotionEntry* splitMotionEntry = splitMotionEvent(
2037 originalMotionEntry, inputTarget->pointerIds);
2038 if (!splitMotionEntry) {
2039 return; // split event was dropped
2040 }
2041#if DEBUG_FOCUS
2042 ALOGD("channel '%s' ~ Split motion event.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002043 connection->getInputChannelName().c_str());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002044 logOutboundMotionDetails(" ", splitMotionEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002045#endif
2046 enqueueDispatchEntriesLocked(currentTime, connection,
2047 splitMotionEntry, inputTarget);
2048 splitMotionEntry->release();
2049 return;
2050 }
2051 }
2052
2053 // Not splitting. Enqueue dispatch entries for the event as is.
2054 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2055}
2056
2057void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
2058 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002059 if (ATRACE_ENABLED()) {
2060 std::string message = StringPrintf(
2061 "enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2062 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
2063 ATRACE_NAME(message.c_str());
2064 }
2065
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002066 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067
2068 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002069 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002070 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002071 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002072 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002073 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002074 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002075 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002076 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002077 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002078 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002079 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002080 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
2081
2082 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002083 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002084 startDispatchCycleLocked(currentTime, connection);
2085 }
2086}
2087
chaviw8c9cf542019-03-25 13:02:48 -07002088void InputDispatcher::enqueueDispatchEntryLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002089 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
2090 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002091 if (ATRACE_ENABLED()) {
2092 std::string message = StringPrintf(
2093 "enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2094 connection->getInputChannelName().c_str(),
2095 dispatchModeToString(dispatchMode).c_str());
2096 ATRACE_NAME(message.c_str());
2097 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002098 int32_t inputTargetFlags = inputTarget->flags;
2099 if (!(inputTargetFlags & dispatchMode)) {
2100 return;
2101 }
2102 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2103
2104 // This is a new event.
2105 // Enqueue a new dispatch entry onto the outbound queue for this connection.
2106 DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
2107 inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08002108 inputTarget->globalScaleFactor, inputTarget->windowXScale,
2109 inputTarget->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002110
2111 // Apply target flags and update the connection's input state.
2112 switch (eventEntry->type) {
2113 case EventEntry::TYPE_KEY: {
2114 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2115 dispatchEntry->resolvedAction = keyEntry->action;
2116 dispatchEntry->resolvedFlags = keyEntry->flags;
2117
2118 if (!connection->inputState.trackKey(keyEntry,
2119 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2120#if DEBUG_DISPATCH_CYCLE
2121 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002122 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002123#endif
2124 delete dispatchEntry;
2125 return; // skip the inconsistent event
2126 }
2127 break;
2128 }
2129
2130 case EventEntry::TYPE_MOTION: {
2131 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2132 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2133 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2134 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2135 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2136 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2137 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2138 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2139 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2140 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2141 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2142 } else {
2143 dispatchEntry->resolvedAction = motionEntry->action;
2144 }
2145 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
2146 && !connection->inputState.isHovering(
2147 motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
2148#if DEBUG_DISPATCH_CYCLE
2149 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002150 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002151#endif
2152 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2153 }
2154
2155 dispatchEntry->resolvedFlags = motionEntry->flags;
2156 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2157 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2158 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002159 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2160 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2161 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002162
2163 if (!connection->inputState.trackMotion(motionEntry,
2164 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2165#if DEBUG_DISPATCH_CYCLE
2166 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002167 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002168#endif
2169 delete dispatchEntry;
2170 return; // skip the inconsistent event
2171 }
chaviw8c9cf542019-03-25 13:02:48 -07002172
chaviwfd6d3512019-03-25 13:23:49 -07002173 dispatchPointerDownOutsideFocus(motionEntry->source,
chaviw8c9cf542019-03-25 13:02:48 -07002174 dispatchEntry->resolvedAction, inputTarget->inputChannel->getToken());
2175
Michael Wrightd02c5b62014-02-10 15:10:22 -08002176 break;
2177 }
2178 }
2179
2180 // Remember that we are waiting for this dispatch to complete.
2181 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002182 incrementPendingForegroundDispatches(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002183 }
2184
2185 // Enqueue the dispatch entry.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002186 connection->outboundQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002187 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002188
2189}
2190
chaviwfd6d3512019-03-25 13:23:49 -07002191void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
chaviw8c9cf542019-03-25 13:02:48 -07002192 const sp<IBinder>& newToken) {
2193 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002194 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2195 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002196 return;
2197 }
2198
2199 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2200 if (inputWindowHandle == nullptr) {
2201 return;
2202 }
2203
chaviw8c9cf542019-03-25 13:02:48 -07002204 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002205 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002206
2207 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2208
2209 if (!hasFocusChanged) {
2210 return;
2211 }
2212
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002213 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2214 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002215 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002216 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002217}
2218
2219void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
2220 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002221 if (ATRACE_ENABLED()) {
2222 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
2223 connection->getInputChannelName().c_str());
2224 ATRACE_NAME(message.c_str());
2225 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002226#if DEBUG_DISPATCH_CYCLE
2227 ALOGD("channel '%s' ~ startDispatchCycle",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002228 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002229#endif
2230
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002231 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2232 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002233 dispatchEntry->deliveryTime = currentTime;
2234
2235 // Publish the event.
2236 status_t status;
2237 EventEntry* eventEntry = dispatchEntry->eventEntry;
2238 switch (eventEntry->type) {
2239 case EventEntry::TYPE_KEY: {
2240 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2241
2242 // Publish the key event.
2243 status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002244 keyEntry->deviceId, keyEntry->source, keyEntry->displayId,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002245 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
2246 keyEntry->keyCode, keyEntry->scanCode,
2247 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
2248 keyEntry->eventTime);
2249 break;
2250 }
2251
2252 case EventEntry::TYPE_MOTION: {
2253 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2254
2255 PointerCoords scaledCoords[MAX_POINTERS];
2256 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2257
2258 // Set the X and Y offset depending on the input source.
Siarhei Vishniakou635cb712017-11-01 16:32:14 -07002259 float xOffset, yOffset;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002260 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
2261 && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
Robert Carre07e1032018-11-26 12:55:53 -08002262 float globalScaleFactor = dispatchEntry->globalScaleFactor;
2263 float wxs = dispatchEntry->windowXScale;
2264 float wys = dispatchEntry->windowYScale;
2265 xOffset = dispatchEntry->xOffset * wxs;
2266 yOffset = dispatchEntry->yOffset * wys;
2267 if (wxs != 1.0f || wys != 1.0f || globalScaleFactor != 1.0f) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002268 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002269 scaledCoords[i] = motionEntry->pointerCoords[i];
Robert Carre07e1032018-11-26 12:55:53 -08002270 scaledCoords[i].scale(globalScaleFactor, wxs, wys);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002271 }
2272 usingCoords = scaledCoords;
2273 }
2274 } else {
2275 xOffset = 0.0f;
2276 yOffset = 0.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002277
2278 // We don't want the dispatch target to know.
2279 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002280 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002281 scaledCoords[i].clear();
2282 }
2283 usingCoords = scaledCoords;
2284 }
2285 }
2286
2287 // Publish the motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002288 status =
2289 connection->inputPublisher
2290 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2291 motionEntry->source, motionEntry->displayId,
2292 dispatchEntry->resolvedAction,
2293 motionEntry->actionButton,
2294 dispatchEntry->resolvedFlags,
2295 motionEntry->edgeFlags, motionEntry->metaState,
2296 motionEntry->buttonState,
2297 motionEntry->classification, xOffset, yOffset,
2298 motionEntry->xPrecision, motionEntry->yPrecision,
2299 motionEntry->xCursorPosition,
2300 motionEntry->yCursorPosition, motionEntry->downTime,
2301 motionEntry->eventTime, motionEntry->pointerCount,
2302 motionEntry->pointerProperties, usingCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002303 break;
2304 }
2305
2306 default:
2307 ALOG_ASSERT(false);
2308 return;
2309 }
2310
2311 // Check the result.
2312 if (status) {
2313 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002314 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002315 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
2316 "This is unexpected because the wait queue is empty, so the pipe "
2317 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002318 "event to it, status=%d", connection->getInputChannelName().c_str(),
2319 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002320 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2321 } else {
2322 // Pipe is full and we are waiting for the app to finish process some events
2323 // before sending more events to it.
2324#if DEBUG_DISPATCH_CYCLE
2325 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
2326 "waiting for the application to catch up",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002327 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002328#endif
2329 connection->inputPublisherBlocked = true;
2330 }
2331 } else {
2332 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002333 "status=%d", connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002334 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2335 }
2336 return;
2337 }
2338
2339 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002340 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2341 connection->outboundQueue.end(),
2342 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002343 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002344 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002345 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002346 }
2347}
2348
2349void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
2350 const sp<Connection>& connection, uint32_t seq, bool handled) {
2351#if DEBUG_DISPATCH_CYCLE
2352 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002353 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002354#endif
2355
2356 connection->inputPublisherBlocked = false;
2357
2358 if (connection->status == Connection::STATUS_BROKEN
2359 || connection->status == Connection::STATUS_ZOMBIE) {
2360 return;
2361 }
2362
2363 // Notify other system components and prepare to start the next dispatch cycle.
2364 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2365}
2366
2367void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
2368 const sp<Connection>& connection, bool notify) {
2369#if DEBUG_DISPATCH_CYCLE
2370 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002371 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002372#endif
2373
2374 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002375 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002376 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002377 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002378 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002379
2380 // The connection appears to be unrecoverably broken.
2381 // Ignore already broken or zombie connections.
2382 if (connection->status == Connection::STATUS_NORMAL) {
2383 connection->status = Connection::STATUS_BROKEN;
2384
2385 if (notify) {
2386 // Notify other system components.
2387 onDispatchCycleBrokenLocked(currentTime, connection);
2388 }
2389 }
2390}
2391
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002392void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2393 while (!queue.empty()) {
2394 DispatchEntry* dispatchEntry = queue.front();
2395 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002396 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002397 }
2398}
2399
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002400void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002401 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002402 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002403 }
2404 delete dispatchEntry;
2405}
2406
2407int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2408 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2409
2410 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002411 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002412
2413 ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
2414 if (connectionIndex < 0) {
2415 ALOGE("Received spurious receive callback for unknown input channel. "
2416 "fd=%d, events=0x%x", fd, events);
2417 return 0; // remove the callback
2418 }
2419
2420 bool notify;
2421 sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
2422 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2423 if (!(events & ALOOPER_EVENT_INPUT)) {
2424 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002425 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002426 return 1;
2427 }
2428
2429 nsecs_t currentTime = now();
2430 bool gotOne = false;
2431 status_t status;
2432 for (;;) {
2433 uint32_t seq;
2434 bool handled;
2435 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2436 if (status) {
2437 break;
2438 }
2439 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2440 gotOne = true;
2441 }
2442 if (gotOne) {
2443 d->runCommandsLockedInterruptible();
2444 if (status == WOULD_BLOCK) {
2445 return 1;
2446 }
2447 }
2448
2449 notify = status != DEAD_OBJECT || !connection->monitor;
2450 if (notify) {
2451 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002452 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002453 }
2454 } else {
2455 // Monitor channels are never explicitly unregistered.
2456 // We do it automatically when the remote endpoint is closed so don't warn
2457 // about them.
2458 notify = !connection->monitor;
2459 if (notify) {
2460 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002461 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002462 }
2463 }
2464
2465 // Unregister the channel.
2466 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2467 return 0; // remove the callback
2468 } // release lock
2469}
2470
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002471void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked (
Michael Wrightd02c5b62014-02-10 15:10:22 -08002472 const CancelationOptions& options) {
2473 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
2474 synthesizeCancelationEventsForConnectionLocked(
2475 mConnectionsByFd.valueAt(i), options);
2476 }
2477}
2478
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002479void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked (
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002480 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002481 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2482 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2483}
2484
2485void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2486 const CancelationOptions& options,
2487 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2488 for (const auto& it : monitorsByDisplay) {
2489 const std::vector<Monitor>& monitors = it.second;
2490 for (const Monitor& monitor : monitors) {
2491 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002492 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002493 }
2494}
2495
Michael Wrightd02c5b62014-02-10 15:10:22 -08002496void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2497 const sp<InputChannel>& channel, const CancelationOptions& options) {
2498 ssize_t index = getConnectionIndexLocked(channel);
2499 if (index >= 0) {
2500 synthesizeCancelationEventsForConnectionLocked(
2501 mConnectionsByFd.valueAt(index), options);
2502 }
2503}
2504
2505void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2506 const sp<Connection>& connection, const CancelationOptions& options) {
2507 if (connection->status == Connection::STATUS_BROKEN) {
2508 return;
2509 }
2510
2511 nsecs_t currentTime = now();
2512
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002513 std::vector<EventEntry*> cancelationEvents;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002514 connection->inputState.synthesizeCancelationEvents(currentTime,
2515 cancelationEvents, options);
2516
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002517 if (!cancelationEvents.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002518#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002519 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Michael Wrightd02c5b62014-02-10 15:10:22 -08002520 "with reality: %s, mode=%d.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002521 connection->getInputChannelName().c_str(), cancelationEvents.size(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002522 options.reason, options.mode);
2523#endif
2524 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002525 EventEntry* cancelationEventEntry = cancelationEvents[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002526 switch (cancelationEventEntry->type) {
2527 case EventEntry::TYPE_KEY:
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002528 logOutboundKeyDetails("cancel - ",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002529 static_cast<KeyEntry*>(cancelationEventEntry));
2530 break;
2531 case EventEntry::TYPE_MOTION:
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002532 logOutboundMotionDetails("cancel - ",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002533 static_cast<MotionEntry*>(cancelationEventEntry));
2534 break;
2535 }
2536
2537 InputTarget target;
chaviwfbe5d9c2018-12-26 12:23:37 -08002538 sp<InputWindowHandle> windowHandle = getWindowHandleLocked(
2539 connection->inputChannel->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07002540 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002541 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2542 target.xOffset = -windowInfo->frameLeft;
2543 target.yOffset = -windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08002544 target.globalScaleFactor = windowInfo->globalScaleFactor;
2545 target.windowXScale = windowInfo->windowXScale;
2546 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002547 } else {
2548 target.xOffset = 0;
2549 target.yOffset = 0;
Robert Carre07e1032018-11-26 12:55:53 -08002550 target.globalScaleFactor = 1.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002551 }
2552 target.inputChannel = connection->inputChannel;
2553 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2554
chaviw8c9cf542019-03-25 13:02:48 -07002555 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
Michael Wrightd02c5b62014-02-10 15:10:22 -08002556 &target, InputTarget::FLAG_DISPATCH_AS_IS);
2557
2558 cancelationEventEntry->release();
2559 }
2560
2561 startDispatchCycleLocked(currentTime, connection);
2562 }
2563}
2564
2565InputDispatcher::MotionEntry*
2566InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2567 ALOG_ASSERT(pointerIds.value != 0);
2568
2569 uint32_t splitPointerIndexMap[MAX_POINTERS];
2570 PointerProperties splitPointerProperties[MAX_POINTERS];
2571 PointerCoords splitPointerCoords[MAX_POINTERS];
2572
2573 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2574 uint32_t splitPointerCount = 0;
2575
2576 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2577 originalPointerIndex++) {
2578 const PointerProperties& pointerProperties =
2579 originalMotionEntry->pointerProperties[originalPointerIndex];
2580 uint32_t pointerId = uint32_t(pointerProperties.id);
2581 if (pointerIds.hasBit(pointerId)) {
2582 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2583 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2584 splitPointerCoords[splitPointerCount].copyFrom(
2585 originalMotionEntry->pointerCoords[originalPointerIndex]);
2586 splitPointerCount += 1;
2587 }
2588 }
2589
2590 if (splitPointerCount != pointerIds.count()) {
2591 // This is bad. We are missing some of the pointers that we expected to deliver.
2592 // Most likely this indicates that we received an ACTION_MOVE events that has
2593 // different pointer ids than we expected based on the previous ACTION_DOWN
2594 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2595 // in this way.
2596 ALOGW("Dropping split motion event because the pointer count is %d but "
2597 "we expected there to be %d pointers. This probably means we received "
2598 "a broken sequence of pointer ids from the input device.",
2599 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002600 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002601 }
2602
2603 int32_t action = originalMotionEntry->action;
2604 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2605 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2606 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2607 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2608 const PointerProperties& pointerProperties =
2609 originalMotionEntry->pointerProperties[originalPointerIndex];
2610 uint32_t pointerId = uint32_t(pointerProperties.id);
2611 if (pointerIds.hasBit(pointerId)) {
2612 if (pointerIds.count() == 1) {
2613 // The first/last pointer went down/up.
2614 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2615 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2616 } else {
2617 // A secondary pointer went down/up.
2618 uint32_t splitPointerIndex = 0;
2619 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2620 splitPointerIndex += 1;
2621 }
2622 action = maskedAction | (splitPointerIndex
2623 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2624 }
2625 } else {
2626 // An unrelated pointer changed.
2627 action = AMOTION_EVENT_ACTION_MOVE;
2628 }
2629 }
2630
Garfield Tan00f511d2019-06-12 16:55:40 -07002631 MotionEntry* splitMotionEntry =
2632 new MotionEntry(originalMotionEntry->sequenceNum, originalMotionEntry->eventTime,
2633 originalMotionEntry->deviceId, originalMotionEntry->source,
2634 originalMotionEntry->displayId, originalMotionEntry->policyFlags,
2635 action, originalMotionEntry->actionButton, originalMotionEntry->flags,
2636 originalMotionEntry->metaState, originalMotionEntry->buttonState,
2637 originalMotionEntry->classification, originalMotionEntry->edgeFlags,
2638 originalMotionEntry->xPrecision, originalMotionEntry->yPrecision,
2639 originalMotionEntry->xCursorPosition,
2640 originalMotionEntry->yCursorPosition, originalMotionEntry->downTime,
2641 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002642
2643 if (originalMotionEntry->injectionState) {
2644 splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2645 splitMotionEntry->injectionState->refCount += 1;
2646 }
2647
2648 return splitMotionEntry;
2649}
2650
2651void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2652#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002653 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002654#endif
2655
2656 bool needWake;
2657 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002658 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002659
Prabir Pradhan42611e02018-11-27 14:04:02 -08002660 ConfigurationChangedEntry* newEntry =
2661 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002662 needWake = enqueueInboundEventLocked(newEntry);
2663 } // release lock
2664
2665 if (needWake) {
2666 mLooper->wake();
2667 }
2668}
2669
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002670/**
2671 * If one of the meta shortcuts is detected, process them here:
2672 * Meta + Backspace -> generate BACK
2673 * Meta + Enter -> generate HOME
2674 * This will potentially overwrite keyCode and metaState.
2675 */
2676void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
2677 int32_t& keyCode, int32_t& metaState) {
2678 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2679 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2680 if (keyCode == AKEYCODE_DEL) {
2681 newKeyCode = AKEYCODE_BACK;
2682 } else if (keyCode == AKEYCODE_ENTER) {
2683 newKeyCode = AKEYCODE_HOME;
2684 }
2685 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002686 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002687 struct KeyReplacement replacement = {keyCode, deviceId};
2688 mReplacedKeys.add(replacement, newKeyCode);
2689 keyCode = newKeyCode;
2690 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2691 }
2692 } else if (action == AKEY_EVENT_ACTION_UP) {
2693 // In order to maintain a consistent stream of up and down events, check to see if the key
2694 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2695 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002696 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002697 struct KeyReplacement replacement = {keyCode, deviceId};
2698 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2699 if (index >= 0) {
2700 keyCode = mReplacedKeys.valueAt(index);
2701 mReplacedKeys.removeItemsAt(index);
2702 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2703 }
2704 }
2705}
2706
Michael Wrightd02c5b62014-02-10 15:10:22 -08002707void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2708#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002709 ALOGD("notifyKey - eventTime=%" PRId64
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002710 ", deviceId=%d, source=0x%x, displayId=%" PRId32 "policyFlags=0x%x, action=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +08002711 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002712 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002713 args->action, args->flags, args->keyCode, args->scanCode,
Arthur Hung82a4cad2018-11-15 12:10:30 +08002714 args->metaState, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002715#endif
2716 if (!validateKeyEvent(args->action)) {
2717 return;
2718 }
2719
2720 uint32_t policyFlags = args->policyFlags;
2721 int32_t flags = args->flags;
2722 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002723 // InputDispatcher tracks and generates key repeats on behalf of
2724 // whatever notifies it, so repeatCount should always be set to 0
2725 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002726 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2727 policyFlags |= POLICY_FLAG_VIRTUAL;
2728 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2729 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002730 if (policyFlags & POLICY_FLAG_FUNCTION) {
2731 metaState |= AMETA_FUNCTION_ON;
2732 }
2733
2734 policyFlags |= POLICY_FLAG_TRUSTED;
2735
Michael Wright78f24442014-08-06 15:55:28 -07002736 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002737 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002738
Michael Wrightd02c5b62014-02-10 15:10:22 -08002739 KeyEvent event;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002740 event.initialize(args->deviceId, args->source, args->displayId, args->action,
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002741 flags, keyCode, args->scanCode, metaState, repeatCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002742 args->downTime, args->eventTime);
2743
Michael Wright2b3c3302018-03-02 17:19:13 +00002744 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002745 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002746 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2747 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2748 std::to_string(t.duration().count()).c_str());
2749 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002750
Michael Wrightd02c5b62014-02-10 15:10:22 -08002751 bool needWake;
2752 { // acquire lock
2753 mLock.lock();
2754
2755 if (shouldSendKeyToInputFilterLocked(args)) {
2756 mLock.unlock();
2757
2758 policyFlags |= POLICY_FLAG_FILTERED;
2759 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2760 return; // event was consumed by the filter
2761 }
2762
2763 mLock.lock();
2764 }
2765
Prabir Pradhan42611e02018-11-27 14:04:02 -08002766 KeyEntry* newEntry = new KeyEntry(args->sequenceNum, args->eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002767 args->deviceId, args->source, args->displayId, policyFlags,
Michael Wright78f24442014-08-06 15:55:28 -07002768 args->action, flags, keyCode, args->scanCode,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002769 metaState, repeatCount, args->downTime);
2770
2771 needWake = enqueueInboundEventLocked(newEntry);
2772 mLock.unlock();
2773 } // release lock
2774
2775 if (needWake) {
2776 mLooper->wake();
2777 }
2778}
2779
2780bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2781 return mInputFilterEnabled;
2782}
2783
2784void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2785#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002786 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07002787 ", policyFlags=0x%x, "
2788 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
2789 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07002790 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07002791 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2792 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
2793 args->edgeFlags, args->xPrecision, args->yPrecision, arg->xCursorPosition,
2794 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002795 for (uint32_t i = 0; i < args->pointerCount; i++) {
2796 ALOGD(" Pointer %d: id=%d, toolType=%d, "
2797 "x=%f, y=%f, pressure=%f, size=%f, "
2798 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2799 "orientation=%f",
2800 i, args->pointerProperties[i].id,
2801 args->pointerProperties[i].toolType,
2802 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2803 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2804 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2805 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2806 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2807 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2808 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2809 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2810 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2811 }
2812#endif
Michael Wright7b159c92015-05-14 14:48:03 +01002813 if (!validateMotionEvent(args->action, args->actionButton,
2814 args->pointerCount, args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002815 return;
2816 }
2817
2818 uint32_t policyFlags = args->policyFlags;
2819 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00002820
2821 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002822 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002823 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2824 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2825 std::to_string(t.duration().count()).c_str());
2826 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002827
2828 bool needWake;
2829 { // acquire lock
2830 mLock.lock();
2831
2832 if (shouldSendMotionToInputFilterLocked(args)) {
2833 mLock.unlock();
2834
2835 MotionEvent event;
Garfield Tan00f511d2019-06-12 16:55:40 -07002836 event.initialize(args->deviceId, args->source, args->displayId, args->action,
2837 args->actionButton, args->flags, args->edgeFlags, args->metaState,
2838 args->buttonState, args->classification, 0, 0, args->xPrecision,
2839 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2840 args->downTime, args->eventTime, args->pointerCount,
2841 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002842
2843 policyFlags |= POLICY_FLAG_FILTERED;
2844 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2845 return; // event was consumed by the filter
2846 }
2847
2848 mLock.lock();
2849 }
2850
2851 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002852 MotionEntry* newEntry =
2853 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2854 args->displayId, policyFlags, args->action, args->actionButton,
2855 args->flags, args->metaState, args->buttonState,
2856 args->classification, args->edgeFlags, args->xPrecision,
2857 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2858 args->downTime, args->pointerCount, args->pointerProperties,
2859 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002860
2861 needWake = enqueueInboundEventLocked(newEntry);
2862 mLock.unlock();
2863 } // release lock
2864
2865 if (needWake) {
2866 mLooper->wake();
2867 }
2868}
2869
2870bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08002871 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002872}
2873
2874void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2875#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002876 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
2877 "switchMask=0x%08x",
2878 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002879#endif
2880
2881 uint32_t policyFlags = args->policyFlags;
2882 policyFlags |= POLICY_FLAG_TRUSTED;
2883 mPolicy->notifySwitch(args->eventTime,
2884 args->switchValues, args->switchMask, policyFlags);
2885}
2886
2887void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
2888#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002889 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002890 args->eventTime, args->deviceId);
2891#endif
2892
2893 bool needWake;
2894 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002895 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002896
Prabir Pradhan42611e02018-11-27 14:04:02 -08002897 DeviceResetEntry* newEntry =
2898 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002899 needWake = enqueueInboundEventLocked(newEntry);
2900 } // release lock
2901
2902 if (needWake) {
2903 mLooper->wake();
2904 }
2905}
2906
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002907int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002908 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
2909 uint32_t policyFlags) {
2910#if DEBUG_INBOUND_EVENT_DETAILS
2911 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002912 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2913 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002914#endif
2915
2916 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2917
2918 policyFlags |= POLICY_FLAG_INJECTED;
2919 if (hasInjectionPermission(injectorPid, injectorUid)) {
2920 policyFlags |= POLICY_FLAG_TRUSTED;
2921 }
2922
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07002923 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924 switch (event->getType()) {
2925 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002926 KeyEvent keyEvent;
2927 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
2928 int32_t action = keyEvent.getAction();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002929 if (! validateKeyEvent(action)) {
2930 return INPUT_EVENT_INJECTION_FAILED;
2931 }
2932
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002933 int32_t flags = keyEvent.getFlags();
2934 int32_t keyCode = keyEvent.getKeyCode();
2935 int32_t metaState = keyEvent.getMetaState();
2936 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
2937 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002938 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002939 action, flags, keyCode, keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002940 keyEvent.getDownTime(), keyEvent.getEventTime());
2941
Michael Wrightd02c5b62014-02-10 15:10:22 -08002942 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2943 policyFlags |= POLICY_FLAG_VIRTUAL;
2944 }
2945
2946 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wright2b3c3302018-03-02 17:19:13 +00002947 android::base::Timer t;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002948 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002949 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2950 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2951 std::to_string(t.duration().count()).c_str());
2952 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002953 }
2954
Michael Wrightd02c5b62014-02-10 15:10:22 -08002955 mLock.lock();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07002956 KeyEntry* injectedEntry =
2957 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
2958 keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
2959 policyFlags, action, flags, keyEvent.getKeyCode(),
2960 keyEvent.getScanCode(), keyEvent.getMetaState(),
2961 keyEvent.getRepeatCount(), keyEvent.getDownTime());
2962 injectedEntries.push(injectedEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002963 break;
2964 }
2965
2966 case AINPUT_EVENT_TYPE_MOTION: {
2967 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002968 int32_t action = motionEvent->getAction();
2969 size_t pointerCount = motionEvent->getPointerCount();
2970 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
Michael Wright7b159c92015-05-14 14:48:03 +01002971 int32_t actionButton = motionEvent->getActionButton();
Charles Chen3611f1f2019-01-29 17:26:18 +08002972 int32_t displayId = motionEvent->getDisplayId();
Michael Wright7b159c92015-05-14 14:48:03 +01002973 if (! validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002974 return INPUT_EVENT_INJECTION_FAILED;
2975 }
2976
2977 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2978 nsecs_t eventTime = motionEvent->getEventTime();
Michael Wright2b3c3302018-03-02 17:19:13 +00002979 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002980 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002981 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2982 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2983 std::to_string(t.duration().count()).c_str());
2984 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002985 }
2986
2987 mLock.lock();
2988 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2989 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07002990 MotionEntry* injectedEntry =
Garfield Tan00f511d2019-06-12 16:55:40 -07002991 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
2992 motionEvent->getDeviceId(), motionEvent->getSource(),
2993 motionEvent->getDisplayId(), policyFlags, action, actionButton,
2994 motionEvent->getFlags(), motionEvent->getMetaState(),
2995 motionEvent->getButtonState(), motionEvent->getClassification(),
2996 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
2997 motionEvent->getYPrecision(), motionEvent->getRawXCursorPosition(),
2998 motionEvent->getRawYCursorPosition(), motionEvent->getDownTime(),
2999 uint32_t(pointerCount), pointerProperties, samplePointerCoords,
3000 motionEvent->getXOffset(), motionEvent->getYOffset());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003001 injectedEntries.push(injectedEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003002 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3003 sampleEventTimes += 1;
3004 samplePointerCoords += pointerCount;
Garfield Tan00f511d2019-06-12 16:55:40 -07003005 MotionEntry* nextInjectedEntry =
3006 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3007 motionEvent->getDeviceId(), motionEvent->getSource(),
3008 motionEvent->getDisplayId(), policyFlags, action, actionButton,
3009 motionEvent->getFlags(), motionEvent->getMetaState(),
3010 motionEvent->getButtonState(), motionEvent->getClassification(),
3011 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3012 motionEvent->getYPrecision(),
3013 motionEvent->getRawXCursorPosition(),
3014 motionEvent->getRawYCursorPosition(),
3015 motionEvent->getDownTime(), uint32_t(pointerCount),
3016 pointerProperties, samplePointerCoords,
3017 motionEvent->getXOffset(), motionEvent->getYOffset());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003018 injectedEntries.push(nextInjectedEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003019 }
3020 break;
3021 }
3022
3023 default:
3024 ALOGW("Cannot inject event of type %d", event->getType());
3025 return INPUT_EVENT_INJECTION_FAILED;
3026 }
3027
3028 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3029 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3030 injectionState->injectionIsAsync = true;
3031 }
3032
3033 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003034 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003035
3036 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003037 while (!injectedEntries.empty()) {
3038 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3039 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003040 }
3041
3042 mLock.unlock();
3043
3044 if (needWake) {
3045 mLooper->wake();
3046 }
3047
3048 int32_t injectionResult;
3049 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003050 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003051
3052 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3053 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3054 } else {
3055 for (;;) {
3056 injectionResult = injectionState->injectionResult;
3057 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3058 break;
3059 }
3060
3061 nsecs_t remainingTimeout = endTime - now();
3062 if (remainingTimeout <= 0) {
3063#if DEBUG_INJECTION
3064 ALOGD("injectInputEvent - Timed out waiting for injection result "
3065 "to become available.");
3066#endif
3067 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3068 break;
3069 }
3070
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003071 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003072 }
3073
3074 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
3075 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
3076 while (injectionState->pendingForegroundDispatches != 0) {
3077#if DEBUG_INJECTION
3078 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
3079 injectionState->pendingForegroundDispatches);
3080#endif
3081 nsecs_t remainingTimeout = endTime - now();
3082 if (remainingTimeout <= 0) {
3083#if DEBUG_INJECTION
3084 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3085 "dispatches to finish.");
3086#endif
3087 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3088 break;
3089 }
3090
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003091 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003092 }
3093 }
3094 }
3095
3096 injectionState->release();
3097 } // release lock
3098
3099#if DEBUG_INJECTION
3100 ALOGD("injectInputEvent - Finished with result %d. "
3101 "injectorPid=%d, injectorUid=%d",
3102 injectionResult, injectorPid, injectorUid);
3103#endif
3104
3105 return injectionResult;
3106}
3107
3108bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
3109 return injectorUid == 0
3110 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
3111}
3112
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003113void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003114 InjectionState* injectionState = entry->injectionState;
3115 if (injectionState) {
3116#if DEBUG_INJECTION
3117 ALOGD("Setting input event injection result to %d. "
3118 "injectorPid=%d, injectorUid=%d",
3119 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
3120#endif
3121
3122 if (injectionState->injectionIsAsync
3123 && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
3124 // Log the outcome since the injector did not wait for the injection result.
3125 switch (injectionResult) {
3126 case INPUT_EVENT_INJECTION_SUCCEEDED:
3127 ALOGV("Asynchronous input event injection succeeded.");
3128 break;
3129 case INPUT_EVENT_INJECTION_FAILED:
3130 ALOGW("Asynchronous input event injection failed.");
3131 break;
3132 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3133 ALOGW("Asynchronous input event injection permission denied.");
3134 break;
3135 case INPUT_EVENT_INJECTION_TIMED_OUT:
3136 ALOGW("Asynchronous input event injection timed out.");
3137 break;
3138 }
3139 }
3140
3141 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003142 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003143 }
3144}
3145
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003146void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003147 InjectionState* injectionState = entry->injectionState;
3148 if (injectionState) {
3149 injectionState->pendingForegroundDispatches += 1;
3150 }
3151}
3152
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003153void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003154 InjectionState* injectionState = entry->injectionState;
3155 if (injectionState) {
3156 injectionState->pendingForegroundDispatches -= 1;
3157
3158 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003159 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003160 }
3161 }
3162}
3163
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003164std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3165 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003166 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003167}
3168
Michael Wrightd02c5b62014-02-10 15:10:22 -08003169sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003170 const sp<IBinder>& windowHandleToken) 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>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003174 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003175 return windowHandle;
3176 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003177 }
3178 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003179 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003180}
3181
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003182bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003183 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003184 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3185 for (const sp<InputWindowHandle>& handle : windowHandles) {
3186 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003187 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003188 ALOGE("Found window %s in display %" PRId32
3189 ", but it should belong to display %" PRId32,
3190 windowHandle->getName().c_str(), it.first,
3191 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003192 }
3193 return true;
3194 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003195 }
3196 }
3197 return false;
3198}
3199
Robert Carr5c8a0262018-10-03 16:30:44 -07003200sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3201 size_t count = mInputChannelsByToken.count(token);
3202 if (count == 0) {
3203 return nullptr;
3204 }
3205 return mInputChannelsByToken.at(token);
3206}
3207
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003208void InputDispatcher::updateWindowHandlesForDisplayLocked(
3209 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3210 if (inputWindowHandles.empty()) {
3211 // Remove all handles on a display if there are no windows left.
3212 mWindowHandlesByDisplay.erase(displayId);
3213 return;
3214 }
3215
3216 // Since we compare the pointer of input window handles across window updates, we need
3217 // to make sure the handle object for the same window stays unchanged across updates.
3218 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
3219 std::unordered_map<sp<IBinder>, sp<InputWindowHandle>, IBinderHash> oldHandlesByTokens;
3220 for (const sp<InputWindowHandle>& handle : oldHandles) {
3221 oldHandlesByTokens[handle->getToken()] = handle;
3222 }
3223
3224 std::vector<sp<InputWindowHandle>> newHandles;
3225 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3226 if (!handle->updateInfo()) {
3227 // handle no longer valid
3228 continue;
3229 }
3230
3231 const InputWindowInfo* info = handle->getInfo();
3232 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3233 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3234 const bool noInputChannel =
3235 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3236 const bool canReceiveInput =
3237 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3238 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3239 if (canReceiveInput && !noInputChannel) {
3240 ALOGE("Window handle %s has no registered input channel",
3241 handle->getName().c_str());
3242 }
3243 continue;
3244 }
3245
3246 if (info->displayId != displayId) {
3247 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3248 handle->getName().c_str(), displayId, info->displayId);
3249 continue;
3250 }
3251
3252 if (oldHandlesByTokens.find(handle->getToken()) != oldHandlesByTokens.end()) {
3253 const sp<InputWindowHandle> oldHandle = oldHandlesByTokens.at(handle->getToken());
3254 oldHandle->updateFrom(handle);
3255 newHandles.push_back(oldHandle);
3256 } else {
3257 newHandles.push_back(handle);
3258 }
3259 }
3260
3261 // Insert or replace
3262 mWindowHandlesByDisplay[displayId] = newHandles;
3263}
3264
Arthur Hungb92218b2018-08-14 12:00:21 +08003265/**
3266 * Called from InputManagerService, update window handle list by displayId that can receive input.
3267 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3268 * If set an empty list, remove all handles from the specific display.
3269 * For focused handle, check if need to change and send a cancel event to previous one.
3270 * For removed handle, check if need to send a cancel event if already in touch.
3271 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003272void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
chaviw291d88a2019-02-14 10:33:58 -08003273 int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003274#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003275 ALOGD("setInputWindows displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003276#endif
3277 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003278 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003279
Arthur Hungb92218b2018-08-14 12:00:21 +08003280 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003281 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3282 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003283
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003284 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3285
Tiger Huang721e26f2018-07-24 22:26:19 +08003286 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003287 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003288 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3289 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3290 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3291 windowHandle->getInfo()->visible) {
3292 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003293 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003294 if (windowHandle == mLastHoverWindowHandle) {
3295 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003296 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003297 }
3298
3299 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003300 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003301 }
3302
Tiger Huang721e26f2018-07-24 22:26:19 +08003303 sp<InputWindowHandle> oldFocusedWindowHandle =
3304 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3305
3306 if (oldFocusedWindowHandle != newFocusedWindowHandle) {
3307 if (oldFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003308#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003309 ALOGD("Focus left window: %s in display %" PRId32,
3310 oldFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003311#endif
Robert Carr5c8a0262018-10-03 16:30:44 -07003312 sp<InputChannel> focusedInputChannel = getInputChannelLocked(
3313 oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003314 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003315 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3316 "focus left window");
3317 synthesizeCancelationEventsForInputChannelLocked(
3318 focusedInputChannel, options);
3319 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003320 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003321 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003322 if (newFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003323#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003324 ALOGD("Focus entered window: %s in display %" PRId32,
3325 newFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003326#endif
Tiger Huang721e26f2018-07-24 22:26:19 +08003327 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003328 }
Robert Carrf759f162018-11-13 12:57:11 -08003329
3330 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003331 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003332 }
3333
Michael Wrightd02c5b62014-02-10 15:10:22 -08003334 }
3335
Arthur Hungb92218b2018-08-14 12:00:21 +08003336 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3337 if (stateIndex >= 0) {
3338 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Ivan Lozano96f12992017-11-09 14:45:38 -08003339 for (size_t i = 0; i < state.windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003340 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003341 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003342#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003343 ALOGD("Touched window was removed: %s in display %" PRId32,
3344 touchedWindow.windowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003345#endif
Jeff Brownf086ddb2014-02-11 14:28:48 -08003346 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003347 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003348 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003349 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3350 "touched window was removed");
3351 synthesizeCancelationEventsForInputChannelLocked(
3352 touchedInputChannel, options);
3353 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003354 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003355 } else {
3356 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003357 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003358 }
3359 }
3360
3361 // Release information for windows that are no longer present.
3362 // This ensures that unused input channels are released promptly.
3363 // Otherwise, they might stick around until the window handle is destroyed
3364 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003365 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003366 if (!hasWindowHandleLocked(oldWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003367#if DEBUG_FOCUS
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003368 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003369#endif
Arthur Hung3b413f22018-10-26 18:05:34 +08003370 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003371 }
3372 }
3373 } // release lock
3374
3375 // Wake up poll loop since it may need to make new input dispatching choices.
3376 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003377
3378 if (setInputWindowsListener) {
3379 setInputWindowsListener->onSetInputWindowsFinished();
3380 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003381}
3382
3383void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003384 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003385#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003386 ALOGD("setFocusedApplication displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003387#endif
3388 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003389 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003390
Tiger Huang721e26f2018-07-24 22:26:19 +08003391 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3392 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003393 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003394 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3395 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003396 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003397 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003398 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003399 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003400 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003401 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003402 oldFocusedApplicationHandle.clear();
3403 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003404 }
3405
3406#if DEBUG_FOCUS
3407 //logDispatchStateLocked();
3408#endif
3409 } // release lock
3410
3411 // Wake up poll loop since it may need to make new input dispatching choices.
3412 mLooper->wake();
3413}
3414
Tiger Huang721e26f2018-07-24 22:26:19 +08003415/**
3416 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3417 * the display not specified.
3418 *
3419 * We track any unreleased events for each window. If a window loses the ability to receive the
3420 * released event, we will send a cancel event to it. So when the focused display is changed, we
3421 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3422 * display. The display-specified events won't be affected.
3423 */
3424void InputDispatcher::setFocusedDisplay(int32_t displayId) {
3425#if DEBUG_FOCUS
3426 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3427#endif
3428 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003429 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003430
3431 if (mFocusedDisplayId != displayId) {
3432 sp<InputWindowHandle> oldFocusedWindowHandle =
3433 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3434 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003435 sp<InputChannel> inputChannel =
3436 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003437 if (inputChannel != nullptr) {
3438 CancelationOptions options(
Michael Wright3dd60e22019-03-27 22:06:44 +00003439 CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Tiger Huang721e26f2018-07-24 22:26:19 +08003440 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003441 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003442 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3443 }
3444 }
3445 mFocusedDisplayId = displayId;
3446
3447 // Sanity check
3448 sp<InputWindowHandle> newFocusedWindowHandle =
3449 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003450 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003451
Tiger Huang721e26f2018-07-24 22:26:19 +08003452 if (newFocusedWindowHandle == nullptr) {
3453 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3454 if (!mFocusedWindowHandlesByDisplay.empty()) {
3455 ALOGE("But another display has a focused window:");
3456 for (auto& it : mFocusedWindowHandlesByDisplay) {
3457 const int32_t displayId = it.first;
3458 const sp<InputWindowHandle>& windowHandle = it.second;
3459 ALOGE("Display #%" PRId32 " has focused window: '%s'\n",
3460 displayId, windowHandle->getName().c_str());
3461 }
3462 }
3463 }
3464 }
3465
3466#if DEBUG_FOCUS
3467 logDispatchStateLocked();
3468#endif
3469 } // release lock
3470
3471 // Wake up poll loop since it may need to make new input dispatching choices.
3472 mLooper->wake();
3473}
3474
Michael Wrightd02c5b62014-02-10 15:10:22 -08003475void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
3476#if DEBUG_FOCUS
3477 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3478#endif
3479
3480 bool changed;
3481 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003482 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003483
3484 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3485 if (mDispatchFrozen && !frozen) {
3486 resetANRTimeoutsLocked();
3487 }
3488
3489 if (mDispatchEnabled && !enabled) {
3490 resetAndDropEverythingLocked("dispatcher is being disabled");
3491 }
3492
3493 mDispatchEnabled = enabled;
3494 mDispatchFrozen = frozen;
3495 changed = true;
3496 } else {
3497 changed = false;
3498 }
3499
3500#if DEBUG_FOCUS
Tiger Huang721e26f2018-07-24 22:26:19 +08003501 logDispatchStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003502#endif
3503 } // release lock
3504
3505 if (changed) {
3506 // Wake up poll loop since it may need to make new input dispatching choices.
3507 mLooper->wake();
3508 }
3509}
3510
3511void InputDispatcher::setInputFilterEnabled(bool enabled) {
3512#if DEBUG_FOCUS
3513 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3514#endif
3515
3516 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003517 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003518
3519 if (mInputFilterEnabled == enabled) {
3520 return;
3521 }
3522
3523 mInputFilterEnabled = enabled;
3524 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3525 } // release lock
3526
3527 // Wake up poll loop since there might be work to do to drop everything.
3528 mLooper->wake();
3529}
3530
chaviwfbe5d9c2018-12-26 12:23:37 -08003531bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3532 if (fromToken == toToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003533#if DEBUG_FOCUS
chaviwfbe5d9c2018-12-26 12:23:37 -08003534 ALOGD("Trivial transfer to same window.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003535#endif
chaviwfbe5d9c2018-12-26 12:23:37 -08003536 return true;
3537 }
3538
Michael Wrightd02c5b62014-02-10 15:10:22 -08003539 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003540 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003541
chaviwfbe5d9c2018-12-26 12:23:37 -08003542 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3543 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003544 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003545 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003546 return false;
3547 }
chaviw4f2dd402018-12-26 15:30:27 -08003548#if DEBUG_FOCUS
3549 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3550 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3551#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003552 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
3553#if DEBUG_FOCUS
3554 ALOGD("Cannot transfer focus because windows are on different displays.");
3555#endif
3556 return false;
3557 }
3558
3559 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003560 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3561 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3562 for (size_t i = 0; i < state.windows.size(); i++) {
3563 const TouchedWindow& touchedWindow = state.windows[i];
3564 if (touchedWindow.windowHandle == fromWindowHandle) {
3565 int32_t oldTargetFlags = touchedWindow.targetFlags;
3566 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003567
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003568 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003569
Jeff Brownf086ddb2014-02-11 14:28:48 -08003570 int32_t newTargetFlags = oldTargetFlags
3571 & (InputTarget::FLAG_FOREGROUND
3572 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
3573 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003574
Jeff Brownf086ddb2014-02-11 14:28:48 -08003575 found = true;
3576 goto Found;
3577 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003578 }
3579 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003580Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003581
3582 if (! found) {
3583#if DEBUG_FOCUS
3584 ALOGD("Focus transfer failed because from window did not have focus.");
3585#endif
3586 return false;
3587 }
3588
chaviwfbe5d9c2018-12-26 12:23:37 -08003589
3590 sp<InputChannel> fromChannel = getInputChannelLocked(fromToken);
3591 sp<InputChannel> toChannel = getInputChannelLocked(toToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003592 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
3593 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
3594 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
3595 sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
3596 sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
3597
3598 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
3599 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3600 "transferring touch focus from this window to another window");
3601 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
3602 }
3603
3604#if DEBUG_FOCUS
3605 logDispatchStateLocked();
3606#endif
3607 } // release lock
3608
3609 // Wake up poll loop since it may need to make new input dispatching choices.
3610 mLooper->wake();
3611 return true;
3612}
3613
3614void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
3615#if DEBUG_FOCUS
3616 ALOGD("Resetting and dropping all events (%s).", reason);
3617#endif
3618
3619 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3620 synthesizeCancelationEventsForAllConnectionsLocked(options);
3621
3622 resetKeyRepeatLocked();
3623 releasePendingEventLocked();
3624 drainInboundQueueLocked();
3625 resetANRTimeoutsLocked();
3626
Jeff Brownf086ddb2014-02-11 14:28:48 -08003627 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003628 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003629 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003630}
3631
3632void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003633 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003634 dumpDispatchStateLocked(dump);
3635
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003636 std::istringstream stream(dump);
3637 std::string line;
3638
3639 while (std::getline(stream, line, '\n')) {
3640 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003641 }
3642}
3643
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003644void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003645 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3646 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3647 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003648 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003649
Tiger Huang721e26f2018-07-24 22:26:19 +08003650 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3651 dump += StringPrintf(INDENT "FocusedApplications:\n");
3652 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3653 const int32_t displayId = it.first;
3654 const sp<InputApplicationHandle>& applicationHandle = it.second;
3655 dump += StringPrintf(
3656 INDENT2 "displayId=%" PRId32 ", name='%s', dispatchingTimeout=%0.3fms\n",
3657 displayId,
3658 applicationHandle->getName().c_str(),
3659 applicationHandle->getDispatchingTimeout(
3660 DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
3661 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003662 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003663 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003664 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003665
3666 if (!mFocusedWindowHandlesByDisplay.empty()) {
3667 dump += StringPrintf(INDENT "FocusedWindows:\n");
3668 for (auto& it : mFocusedWindowHandlesByDisplay) {
3669 const int32_t displayId = it.first;
3670 const sp<InputWindowHandle>& windowHandle = it.second;
3671 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n",
3672 displayId, windowHandle->getName().c_str());
3673 }
3674 } else {
3675 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3676 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003677
Jeff Brownf086ddb2014-02-11 14:28:48 -08003678 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003679 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003680 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3681 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003682 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Jeff Brownf086ddb2014-02-11 14:28:48 -08003683 state.displayId, toString(state.down), toString(state.split),
3684 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003685 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003686 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003687 for (size_t i = 0; i < state.windows.size(); i++) {
3688 const TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003689 dump += StringPrintf(INDENT4 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3690 i, touchedWindow.windowHandle->getName().c_str(),
Jeff Brownf086ddb2014-02-11 14:28:48 -08003691 touchedWindow.pointerIds.value,
3692 touchedWindow.targetFlags);
3693 }
3694 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003695 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003696 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003697 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003698 dump += INDENT3 "Portal windows:\n";
3699 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003700 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003701 dump += StringPrintf(INDENT4 "%zu: name='%s'\n",
3702 i, portalWindowHandle->getName().c_str());
3703 }
3704 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003705 }
3706 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003707 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003708 }
3709
Arthur Hungb92218b2018-08-14 12:00:21 +08003710 if (!mWindowHandlesByDisplay.empty()) {
3711 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003712 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003713 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003714 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003715 dump += INDENT2 "Windows:\n";
3716 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003717 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003718 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003719
Arthur Hungb92218b2018-08-14 12:00:21 +08003720 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003721 "portalToDisplayId=%d, paused=%s, hasFocus=%s, hasWallpaper=%s, "
Arthur Hungb92218b2018-08-14 12:00:21 +08003722 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
Riddle Hsu39d4aa52018-11-30 20:46:53 +08003723 "frame=[%d,%d][%d,%d], globalScale=%f, windowScale=(%f,%f), "
Arthur Hungb92218b2018-08-14 12:00:21 +08003724 "touchableRegion=",
3725 i, windowInfo->name.c_str(), windowInfo->displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003726 windowInfo->portalToDisplayId,
Arthur Hungb92218b2018-08-14 12:00:21 +08003727 toString(windowInfo->paused),
3728 toString(windowInfo->hasFocus),
3729 toString(windowInfo->hasWallpaper),
3730 toString(windowInfo->visible),
3731 toString(windowInfo->canReceiveKeys),
3732 windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
3733 windowInfo->layer,
3734 windowInfo->frameLeft, windowInfo->frameTop,
3735 windowInfo->frameRight, windowInfo->frameBottom,
Robert Carre07e1032018-11-26 12:55:53 -08003736 windowInfo->globalScaleFactor,
3737 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003738 dumpRegion(dump, windowInfo->touchableRegion);
3739 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3740 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
3741 windowInfo->ownerPid, windowInfo->ownerUid,
3742 windowInfo->dispatchingTimeout / 1000000.0);
3743 }
3744 } else {
3745 dump += INDENT2 "Windows: <none>\n";
3746 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003747 }
3748 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003749 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003750 }
3751
Michael Wright3dd60e22019-03-27 22:06:44 +00003752 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
3753 for (auto& it : mGlobalMonitorsByDisplay) {
3754 const std::vector<Monitor>& monitors = it.second;
3755 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3756 dumpMonitors(dump, monitors);
3757 }
3758 for (auto& it : mGestureMonitorsByDisplay) {
3759 const std::vector<Monitor>& monitors = it.second;
3760 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
3761 dumpMonitors(dump, monitors);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003762 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003763 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00003764 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003765 }
3766
3767 nsecs_t currentTime = now();
3768
3769 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003770 if (!mRecentQueue.empty()) {
3771 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
3772 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003773 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003774 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003775 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003776 (currentTime - entry->eventTime) * 0.000001f);
3777 }
3778 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003779 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003780 }
3781
3782 // Dump event currently being dispatched.
3783 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003784 dump += INDENT "PendingEvent:\n";
3785 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003786 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003787 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003788 (currentTime - mPendingEvent->eventTime) * 0.000001f);
3789 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003790 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003791 }
3792
3793 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003794 if (!mInboundQueue.empty()) {
3795 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
3796 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003797 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003798 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003799 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003800 (currentTime - entry->eventTime) * 0.000001f);
3801 }
3802 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003803 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003804 }
3805
Michael Wright78f24442014-08-06 15:55:28 -07003806 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003807 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07003808 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
3809 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
3810 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003811 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n",
Michael Wright78f24442014-08-06 15:55:28 -07003812 i, replacement.keyCode, replacement.deviceId, newKeyCode);
3813 }
3814 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003815 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07003816 }
3817
Michael Wrightd02c5b62014-02-10 15:10:22 -08003818 if (!mConnectionsByFd.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003819 dump += INDENT "Connections:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003820 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
3821 const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003822 dump += StringPrintf(INDENT2 "%zu: channelName='%s', windowName='%s', "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003823 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08003824 i, connection->getInputChannelName().c_str(),
3825 connection->getWindowName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08003826 connection->getStatusLabel(), toString(connection->monitor),
3827 toString(connection->inputPublisherBlocked));
3828
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003829 if (!connection->outboundQueue.empty()) {
3830 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
3831 connection->outboundQueue.size());
3832 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003833 dump.append(INDENT4);
3834 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003835 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003836 entry->targetFlags, entry->resolvedAction,
3837 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
3838 }
3839 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003840 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003841 }
3842
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003843 if (!connection->waitQueue.empty()) {
3844 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
3845 connection->waitQueue.size());
3846 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003847 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003849 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003850 "age=%0.1fms, wait=%0.1fms\n",
3851 entry->targetFlags, entry->resolvedAction,
3852 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
3853 (currentTime - entry->deliveryTime) * 0.000001f);
3854 }
3855 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003856 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003857 }
3858 }
3859 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003860 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003861 }
3862
3863 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003864 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865 (mAppSwitchDueTime - now()) / 1000000.0);
3866 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003867 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003868 }
3869
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003870 dump += INDENT "Configuration:\n";
3871 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003872 mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003873 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003874 mConfig.keyRepeatTimeout * 0.000001f);
3875}
3876
Michael Wright3dd60e22019-03-27 22:06:44 +00003877void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
3878 const size_t numMonitors = monitors.size();
3879 for (size_t i = 0; i < numMonitors; i++) {
3880 const Monitor& monitor = monitors[i];
3881 const sp<InputChannel>& channel = monitor.inputChannel;
3882 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
3883 dump += "\n";
3884 }
3885}
3886
3887status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3888 int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003889#if DEBUG_REGISTRATION
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003890 ALOGD("channel '%s' ~ registerInputChannel - displayId=%" PRId32,
3891 inputChannel->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003892#endif
3893
3894 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003895 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003896
3897 if (getConnectionIndexLocked(inputChannel) >= 0) {
3898 ALOGW("Attempted to register already registered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003899 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003900 return BAD_VALUE;
3901 }
3902
Michael Wright3dd60e22019-03-27 22:06:44 +00003903 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003904
3905 int fd = inputChannel->getFd();
3906 mConnectionsByFd.add(fd, connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07003907 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003908
Michael Wrightd02c5b62014-02-10 15:10:22 -08003909 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3910 } // release lock
3911
3912 // Wake the looper because some connections have changed.
3913 mLooper->wake();
3914 return OK;
3915}
3916
Michael Wright3dd60e22019-03-27 22:06:44 +00003917status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
3918 int32_t displayId, bool isGestureMonitor) {
3919 { // acquire lock
3920 std::scoped_lock _l(mLock);
3921
3922 if (displayId < 0) {
3923 ALOGW("Attempted to register input monitor without a specified display.");
3924 return BAD_VALUE;
3925 }
3926
3927 if (inputChannel->getToken() == nullptr) {
3928 ALOGW("Attempted to register input monitor without an identifying token.");
3929 return BAD_VALUE;
3930 }
3931
3932 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
3933
3934 const int fd = inputChannel->getFd();
3935 mConnectionsByFd.add(fd, connection);
3936 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
3937
3938 auto& monitorsByDisplay = isGestureMonitor
3939 ? mGestureMonitorsByDisplay
3940 : mGlobalMonitorsByDisplay;
3941 monitorsByDisplay[displayId].emplace_back(inputChannel);
3942
3943 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3944
3945 }
3946 // Wake the looper because some connections have changed.
3947 mLooper->wake();
3948 return OK;
3949}
3950
Michael Wrightd02c5b62014-02-10 15:10:22 -08003951status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
3952#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003953 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003954#endif
3955
3956 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003957 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003958
3959 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3960 if (status) {
3961 return status;
3962 }
3963 } // release lock
3964
3965 // Wake the poll loop because removing the connection may have changed the current
3966 // synchronization state.
3967 mLooper->wake();
3968 return OK;
3969}
3970
3971status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
3972 bool notify) {
3973 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
3974 if (connectionIndex < 0) {
3975 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003976 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003977 return BAD_VALUE;
3978 }
3979
3980 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
3981 mConnectionsByFd.removeItemsAt(connectionIndex);
3982
Robert Carr5c8a0262018-10-03 16:30:44 -07003983 mInputChannelsByToken.erase(inputChannel->getToken());
3984
Michael Wrightd02c5b62014-02-10 15:10:22 -08003985 if (connection->monitor) {
3986 removeMonitorChannelLocked(inputChannel);
3987 }
3988
3989 mLooper->removeFd(inputChannel->getFd());
3990
3991 nsecs_t currentTime = now();
3992 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
3993
3994 connection->status = Connection::STATUS_ZOMBIE;
3995 return OK;
3996}
3997
3998void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003999 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4000 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4001}
4002
4003void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel,
4004 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
4005 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end(); ) {
4006 std::vector<Monitor>& monitors = it->second;
4007 const size_t numMonitors = monitors.size();
4008 for (size_t i = 0; i < numMonitors; i++) {
4009 if (monitors[i].inputChannel == inputChannel) {
4010 monitors.erase(monitors.begin() + i);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004011 break;
4012 }
4013 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004014 if (monitors.empty()) {
4015 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004016 } else {
4017 ++it;
4018 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004019 }
4020}
4021
Michael Wright3dd60e22019-03-27 22:06:44 +00004022status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4023 { // acquire lock
4024 std::scoped_lock _l(mLock);
4025 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4026
4027 if (!foundDisplayId) {
4028 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4029 return BAD_VALUE;
4030 }
4031 int32_t displayId = foundDisplayId.value();
4032
4033 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4034 if (stateIndex < 0) {
4035 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4036 return BAD_VALUE;
4037 }
4038
4039 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4040 std::optional<int32_t> foundDeviceId;
4041 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
4042 if (touchedMonitor.monitor.inputChannel->getToken() == token) {
4043 foundDeviceId = state.deviceId;
4044 }
4045 }
4046 if (!foundDeviceId || !state.down) {
4047 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
4048 " Ignoring.");
4049 return BAD_VALUE;
4050 }
4051 int32_t deviceId = foundDeviceId.value();
4052
4053 // Send cancel events to all the input channels we're stealing from.
4054 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4055 "gesture monitor stole pointer stream");
4056 options.deviceId = deviceId;
4057 options.displayId = displayId;
4058 for (const TouchedWindow& window : state.windows) {
4059 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
4060 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4061 }
4062 // Then clear the current touch state so we stop dispatching to them as well.
4063 state.filterNonMonitors();
4064 }
4065 return OK;
4066}
4067
4068
4069std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4070 const sp<IBinder>& token) {
4071 for (const auto& it : mGestureMonitorsByDisplay) {
4072 const std::vector<Monitor>& monitors = it.second;
4073 for (const Monitor& monitor : monitors) {
4074 if (monitor.inputChannel->getToken() == token) {
4075 return it.first;
4076 }
4077 }
4078 }
4079 return std::nullopt;
4080}
4081
Michael Wrightd02c5b62014-02-10 15:10:22 -08004082ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Robert Carr4e670e52018-08-15 13:26:12 -07004083 if (inputChannel == nullptr) {
Arthur Hung3b413f22018-10-26 18:05:34 +08004084 return -1;
4085 }
4086
Robert Carr4e670e52018-08-15 13:26:12 -07004087 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
4088 sp<Connection> connection = mConnectionsByFd.valueAt(i);
4089 if (connection->inputChannel->getToken() == inputChannel->getToken()) {
4090 return i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004091 }
4092 }
Robert Carr4e670e52018-08-15 13:26:12 -07004093
Michael Wrightd02c5b62014-02-10 15:10:22 -08004094 return -1;
4095}
4096
4097void InputDispatcher::onDispatchCycleFinishedLocked(
4098 nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004099 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4100 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004101 commandEntry->connection = connection;
4102 commandEntry->eventTime = currentTime;
4103 commandEntry->seq = seq;
4104 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004105 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004106}
4107
4108void InputDispatcher::onDispatchCycleBrokenLocked(
4109 nsecs_t currentTime, const sp<Connection>& connection) {
4110 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004111 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004112
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004113 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4114 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004115 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004116 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004117}
4118
chaviw0c06c6e2019-01-09 13:27:07 -08004119void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
4120 const sp<InputWindowHandle>& newFocus) {
4121 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4122 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004123 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4124 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004125 commandEntry->oldToken = oldToken;
4126 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004127 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004128}
4129
Michael Wrightd02c5b62014-02-10 15:10:22 -08004130void InputDispatcher::onANRLocked(
4131 nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
4132 const sp<InputWindowHandle>& windowHandle,
4133 nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
4134 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4135 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4136 ALOGI("Application is not responding: %s. "
4137 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004138 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004139 dispatchLatency, waitDuration, reason);
4140
4141 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004142 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004143 struct tm tm;
4144 localtime_r(&t, &tm);
4145 char timestr[64];
4146 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4147 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004148 mLastANRState += INDENT "ANR:\n";
4149 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
4150 mLastANRState += StringPrintf(INDENT2 "Window: %s\n",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004151 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004152 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4153 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4154 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004155 dumpDispatchStateLocked(mLastANRState);
4156
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004157 std::unique_ptr<CommandEntry> commandEntry =
4158 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004159 commandEntry->inputApplicationHandle = applicationHandle;
Robert Carr5c8a0262018-10-03 16:30:44 -07004160 commandEntry->inputChannel = windowHandle != nullptr ?
4161 getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004162 commandEntry->reason = reason;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004163 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004164}
4165
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004166void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible (
Michael Wrightd02c5b62014-02-10 15:10:22 -08004167 CommandEntry* commandEntry) {
4168 mLock.unlock();
4169
4170 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4171
4172 mLock.lock();
4173}
4174
4175void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
4176 CommandEntry* commandEntry) {
4177 sp<Connection> connection = commandEntry->connection;
4178
4179 if (connection->status != Connection::STATUS_ZOMBIE) {
4180 mLock.unlock();
4181
Robert Carr803535b2018-08-02 16:38:15 -07004182 mPolicy->notifyInputChannelBroken(connection->inputChannel->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004183
4184 mLock.lock();
4185 }
4186}
4187
Robert Carrf759f162018-11-13 12:57:11 -08004188void InputDispatcher::doNotifyFocusChangedLockedInterruptible(
4189 CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004190 sp<IBinder> oldToken = commandEntry->oldToken;
4191 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004192 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004193 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004194 mLock.lock();
4195}
4196
Michael Wrightd02c5b62014-02-10 15:10:22 -08004197void InputDispatcher::doNotifyANRLockedInterruptible(
4198 CommandEntry* commandEntry) {
4199 mLock.unlock();
4200
4201 nsecs_t newTimeout = mPolicy->notifyANR(
Robert Carr803535b2018-08-02 16:38:15 -07004202 commandEntry->inputApplicationHandle,
4203 commandEntry->inputChannel ? commandEntry->inputChannel->getToken() : nullptr,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004204 commandEntry->reason);
4205
4206 mLock.lock();
4207
4208 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
Robert Carr803535b2018-08-02 16:38:15 -07004209 commandEntry->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004210}
4211
4212void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4213 CommandEntry* commandEntry) {
4214 KeyEntry* entry = commandEntry->keyEntry;
4215
4216 KeyEvent event;
4217 initializeKeyEvent(&event, entry);
4218
4219 mLock.unlock();
4220
Michael Wright2b3c3302018-03-02 17:19:13 +00004221 android::base::Timer t;
Robert Carr803535b2018-08-02 16:38:15 -07004222 sp<IBinder> token = commandEntry->inputChannel != nullptr ?
4223 commandEntry->inputChannel->getToken() : nullptr;
4224 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004225 &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004226 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4227 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
4228 std::to_string(t.duration().count()).c_str());
4229 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004230
4231 mLock.lock();
4232
4233 if (delay < 0) {
4234 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4235 } else if (!delay) {
4236 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4237 } else {
4238 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4239 entry->interceptKeyWakeupTime = now() + delay;
4240 }
4241 entry->release();
4242}
4243
chaviwfd6d3512019-03-25 13:23:49 -07004244void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4245 mLock.unlock();
4246 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4247 mLock.lock();
4248}
4249
Michael Wrightd02c5b62014-02-10 15:10:22 -08004250void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
4251 CommandEntry* commandEntry) {
4252 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004253 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004254 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004255 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004256
4257 // Handle post-event policy actions.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004258 std::deque<InputDispatcher::DispatchEntry*>::iterator dispatchEntryIt =
4259 connection->findWaitQueueEntry(seq);
4260 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004261 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004262 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004263 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004264
4265 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4266 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4267 std::string msg =
4268 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4269 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4270 dispatchEntry->eventEntry->appendDescription(msg);
4271 ALOGI("%s", msg.c_str());
4272 }
4273
4274 bool restartEvent;
4275 if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
4276 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4277 restartEvent =
4278 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
4279 } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
4280 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4281 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4282 handled);
4283 } else {
4284 restartEvent = false;
4285 }
4286
4287 // Dequeue the event and start the next cycle.
4288 // Note that because the lock might have been released, it is possible that the
4289 // contents of the wait queue to have been drained, so we need to double-check
4290 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004291 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4292 if (dispatchEntryIt != connection->waitQueue.end()) {
4293 dispatchEntry = *dispatchEntryIt;
4294 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004295 traceWaitQueueLength(connection);
4296 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004297 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004298 traceOutboundQueueLength(connection);
4299 } else {
4300 releaseDispatchEntry(dispatchEntry);
4301 }
4302 }
4303
4304 // Start the next dispatch cycle for this connection.
4305 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004306}
4307
4308bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
4309 DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004310 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004311 if (!handled) {
4312 // Report the key as unhandled, since the fallback was not handled.
4313 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4314 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004315 return false;
4316 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004317
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004318 // Get the fallback key state.
4319 // Clear it out after dispatching the UP.
4320 int32_t originalKeyCode = keyEntry->keyCode;
4321 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4322 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4323 connection->inputState.removeFallbackKey(originalKeyCode);
4324 }
4325
4326 if (handled || !dispatchEntry->hasForegroundTarget()) {
4327 // If the application handles the original key for which we previously
4328 // generated a fallback or if the window is not a foreground window,
4329 // then cancel the associated fallback key, if any.
4330 if (fallbackKeyCode != -1) {
4331 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004332#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004333 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004334 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4335 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4336 keyEntry->policyFlags);
4337#endif
4338 KeyEvent event;
4339 initializeKeyEvent(&event, keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004340 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004341
4342 mLock.unlock();
4343
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004344 mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4345 &event, keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004346
4347 mLock.lock();
4348
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004349 // Cancel the fallback key.
4350 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004351 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004352 "application handled the original non-fallback key "
4353 "or is no longer a foreground target, "
4354 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004355 options.keyCode = fallbackKeyCode;
4356 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004357 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004358 connection->inputState.removeFallbackKey(originalKeyCode);
4359 }
4360 } else {
4361 // If the application did not handle a non-fallback key, first check
4362 // that we are in a good state to perform unhandled key event processing
4363 // Then ask the policy what to do with it.
4364 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
4365 && keyEntry->repeatCount == 0;
4366 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004367#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004368 ALOGD("Unhandled key event: Skipping unhandled key event processing "
4369 "since this is not an initial down. "
4370 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4371 originalKeyCode, keyEntry->action, keyEntry->repeatCount,
4372 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004373#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004374 return false;
4375 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004376
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004377 // Dispatch the unhandled key to the policy.
4378#if DEBUG_OUTBOUND_EVENT_DETAILS
4379 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
4380 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4381 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4382 keyEntry->policyFlags);
4383#endif
4384 KeyEvent event;
4385 initializeKeyEvent(&event, keyEntry);
4386
4387 mLock.unlock();
4388
4389 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4390 &event, keyEntry->policyFlags, &event);
4391
4392 mLock.lock();
4393
4394 if (connection->status != Connection::STATUS_NORMAL) {
4395 connection->inputState.removeFallbackKey(originalKeyCode);
4396 return false;
4397 }
4398
4399 // Latch the fallback keycode for this key on an initial down.
4400 // The fallback keycode cannot change at any other point in the lifecycle.
4401 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004402 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004403 fallbackKeyCode = event.getKeyCode();
4404 } else {
4405 fallbackKeyCode = AKEYCODE_UNKNOWN;
4406 }
4407 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4408 }
4409
4410 ALOG_ASSERT(fallbackKeyCode != -1);
4411
4412 // Cancel the fallback key if the policy decides not to send it anymore.
4413 // We will continue to dispatch the key to the policy but we will no
4414 // longer dispatch a fallback key to the application.
4415 if (fallbackKeyCode != AKEYCODE_UNKNOWN
4416 && (!fallback || fallbackKeyCode != event.getKeyCode())) {
4417#if DEBUG_OUTBOUND_EVENT_DETAILS
4418 if (fallback) {
4419 ALOGD("Unhandled key event: Policy requested to send key %d"
4420 "as a fallback for %d, but on the DOWN it had requested "
4421 "to send %d instead. Fallback canceled.",
4422 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
4423 } else {
4424 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
4425 "but on the DOWN it had requested to send %d. "
4426 "Fallback canceled.",
4427 originalKeyCode, fallbackKeyCode);
4428 }
4429#endif
4430
4431 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4432 "canceling fallback, policy no longer desires it");
4433 options.keyCode = fallbackKeyCode;
4434 synthesizeCancelationEventsForConnectionLocked(connection, options);
4435
4436 fallback = false;
4437 fallbackKeyCode = AKEYCODE_UNKNOWN;
4438 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
4439 connection->inputState.setFallbackKey(originalKeyCode,
4440 fallbackKeyCode);
4441 }
4442 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004443
4444#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004445 {
4446 std::string msg;
4447 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4448 connection->inputState.getFallbackKeys();
4449 for (size_t i = 0; i < fallbackKeys.size(); i++) {
4450 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i),
4451 fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004452 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004453 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
4454 fallbackKeys.size(), msg.c_str());
4455 }
4456#endif
4457
4458 if (fallback) {
4459 // Restart the dispatch cycle using the fallback key.
4460 keyEntry->eventTime = event.getEventTime();
4461 keyEntry->deviceId = event.getDeviceId();
4462 keyEntry->source = event.getSource();
4463 keyEntry->displayId = event.getDisplayId();
4464 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4465 keyEntry->keyCode = fallbackKeyCode;
4466 keyEntry->scanCode = event.getScanCode();
4467 keyEntry->metaState = event.getMetaState();
4468 keyEntry->repeatCount = event.getRepeatCount();
4469 keyEntry->downTime = event.getDownTime();
4470 keyEntry->syntheticRepeat = false;
4471
4472#if DEBUG_OUTBOUND_EVENT_DETAILS
4473 ALOGD("Unhandled key event: Dispatching fallback key. "
4474 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4475 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
4476#endif
4477 return true; // restart the event
4478 } else {
4479#if DEBUG_OUTBOUND_EVENT_DETAILS
4480 ALOGD("Unhandled key event: No fallback key.");
4481#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004482
4483 // Report the key as unhandled, since there is no fallback key.
4484 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004485 }
4486 }
4487 return false;
4488}
4489
4490bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
4491 DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
4492 return false;
4493}
4494
4495void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4496 mLock.unlock();
4497
4498 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4499
4500 mLock.lock();
4501}
4502
4503void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004504 event->initialize(entry->deviceId, entry->source, entry->displayId, entry->action, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004505 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
4506 entry->downTime, entry->eventTime);
4507}
4508
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004509void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry* entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004510 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
4511 // TODO Write some statistics about how long we spend waiting.
4512}
4513
4514void InputDispatcher::traceInboundQueueLengthLocked() {
4515 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004516 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004517 }
4518}
4519
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004520void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004521 if (ATRACE_ENABLED()) {
4522 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004523 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004524 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004525 }
4526}
4527
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004528void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004529 if (ATRACE_ENABLED()) {
4530 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004531 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004532 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004533 }
4534}
4535
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004536void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004537 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004538
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004539 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004540 dumpDispatchStateLocked(dump);
4541
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004542 if (!mLastANRState.empty()) {
4543 dump += "\nInput Dispatcher State at time of last ANR:\n";
4544 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004545 }
4546}
4547
4548void InputDispatcher::monitor() {
4549 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004550 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004551 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004552 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004553}
4554
4555
Michael Wrightd02c5b62014-02-10 15:10:22 -08004556// --- InputDispatcher::InjectionState ---
4557
4558InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
4559 refCount(1),
4560 injectorPid(injectorPid), injectorUid(injectorUid),
4561 injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
4562 pendingForegroundDispatches(0) {
4563}
4564
4565InputDispatcher::InjectionState::~InjectionState() {
4566}
4567
4568void InputDispatcher::InjectionState::release() {
4569 refCount -= 1;
4570 if (refCount == 0) {
4571 delete this;
4572 } else {
4573 ALOG_ASSERT(refCount > 0);
4574 }
4575}
4576
4577
4578// --- InputDispatcher::EventEntry ---
4579
Prabir Pradhan42611e02018-11-27 14:04:02 -08004580InputDispatcher::EventEntry::EventEntry(uint32_t sequenceNum, int32_t type,
4581 nsecs_t eventTime, uint32_t policyFlags) :
4582 sequenceNum(sequenceNum), refCount(1), type(type), eventTime(eventTime),
4583 policyFlags(policyFlags), injectionState(nullptr), dispatchInProgress(false) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004584}
4585
4586InputDispatcher::EventEntry::~EventEntry() {
4587 releaseInjectionState();
4588}
4589
4590void InputDispatcher::EventEntry::release() {
4591 refCount -= 1;
4592 if (refCount == 0) {
4593 delete this;
4594 } else {
4595 ALOG_ASSERT(refCount > 0);
4596 }
4597}
4598
4599void InputDispatcher::EventEntry::releaseInjectionState() {
4600 if (injectionState) {
4601 injectionState->release();
Yi Kong9b14ac62018-07-17 13:48:38 -07004602 injectionState = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004603 }
4604}
4605
4606
4607// --- InputDispatcher::ConfigurationChangedEntry ---
4608
Prabir Pradhan42611e02018-11-27 14:04:02 -08004609InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(
4610 uint32_t sequenceNum, nsecs_t eventTime) :
4611 EventEntry(sequenceNum, TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004612}
4613
4614InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
4615}
4616
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004617void InputDispatcher::ConfigurationChangedEntry::appendDescription(std::string& msg) const {
4618 msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004619}
4620
4621
4622// --- InputDispatcher::DeviceResetEntry ---
4623
Prabir Pradhan42611e02018-11-27 14:04:02 -08004624InputDispatcher::DeviceResetEntry::DeviceResetEntry(
4625 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId) :
4626 EventEntry(sequenceNum, TYPE_DEVICE_RESET, eventTime, 0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004627 deviceId(deviceId) {
4628}
4629
4630InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
4631}
4632
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004633void InputDispatcher::DeviceResetEntry::appendDescription(std::string& msg) const {
4634 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x",
Michael Wrightd02c5b62014-02-10 15:10:22 -08004635 deviceId, policyFlags);
4636}
4637
4638
4639// --- InputDispatcher::KeyEntry ---
4640
Prabir Pradhan42611e02018-11-27 14:04:02 -08004641InputDispatcher::KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004642 int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004643 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
4644 int32_t repeatCount, nsecs_t downTime) :
Prabir Pradhan42611e02018-11-27 14:04:02 -08004645 EventEntry(sequenceNum, TYPE_KEY, eventTime, policyFlags),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004646 deviceId(deviceId), source(source), displayId(displayId), action(action), flags(flags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004647 keyCode(keyCode), scanCode(scanCode), metaState(metaState),
4648 repeatCount(repeatCount), downTime(downTime),
4649 syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
4650 interceptKeyWakeupTime(0) {
4651}
4652
4653InputDispatcher::KeyEntry::~KeyEntry() {
4654}
4655
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004656void InputDispatcher::KeyEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004657 msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004658 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
4659 "repeatCount=%d), policyFlags=0x%08x",
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004660 deviceId, source, displayId, keyActionToString(action).c_str(), flags, keyCode,
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004661 scanCode, metaState, repeatCount, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004662}
4663
4664void InputDispatcher::KeyEntry::recycle() {
4665 releaseInjectionState();
4666
4667 dispatchInProgress = false;
4668 syntheticRepeat = false;
4669 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
4670 interceptKeyWakeupTime = 0;
4671}
4672
4673
4674// --- InputDispatcher::MotionEntry ---
4675
Garfield Tan00f511d2019-06-12 16:55:40 -07004676InputDispatcher::MotionEntry::MotionEntry(
4677 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
4678 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004679 int32_t flags, int32_t metaState, int32_t buttonState, MotionClassification classification,
Garfield Tan00f511d2019-06-12 16:55:40 -07004680 int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition,
4681 float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
Jeff Brownf086ddb2014-02-11 14:28:48 -08004682 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
Garfield Tan00f511d2019-06-12 16:55:40 -07004683 float xOffset, float yOffset)
4684 : EventEntry(sequenceNum, TYPE_MOTION, eventTime, policyFlags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004685 eventTime(eventTime),
Garfield Tan00f511d2019-06-12 16:55:40 -07004686 deviceId(deviceId),
4687 source(source),
4688 displayId(displayId),
4689 action(action),
4690 actionButton(actionButton),
4691 flags(flags),
4692 metaState(metaState),
4693 buttonState(buttonState),
4694 classification(classification),
4695 edgeFlags(edgeFlags),
4696 xPrecision(xPrecision),
4697 yPrecision(yPrecision),
4698 xCursorPosition(xCursorPosition),
4699 yCursorPosition(yCursorPosition),
4700 downTime(downTime),
4701 pointerCount(pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004702 for (uint32_t i = 0; i < pointerCount; i++) {
4703 this->pointerProperties[i].copyFrom(pointerProperties[i]);
4704 this->pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004705 if (xOffset || yOffset) {
4706 this->pointerCoords[i].applyOffset(xOffset, yOffset);
4707 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004708 }
4709}
4710
4711InputDispatcher::MotionEntry::~MotionEntry() {
4712}
4713
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004714void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004715 msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07004716 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
4717 "buttonState=0x%08x, "
4718 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
4719 "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
4720 deviceId, source, displayId, motionActionToString(action).c_str(),
4721 actionButton, flags, metaState, buttonState,
4722 motionClassificationToString(classification), edgeFlags, xPrecision,
4723 yPrecision, xCursorPosition, yCursorPosition);
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004724
Michael Wrightd02c5b62014-02-10 15:10:22 -08004725 for (uint32_t i = 0; i < pointerCount; i++) {
4726 if (i) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004727 msg += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004728 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004729 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004730 pointerCoords[i].getX(), pointerCoords[i].getY());
4731 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004732 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004733}
4734
4735
4736// --- InputDispatcher::DispatchEntry ---
4737
4738volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
4739
4740InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
Robert Carre07e1032018-11-26 12:55:53 -08004741 int32_t targetFlags, float xOffset, float yOffset, float globalScaleFactor,
4742 float windowXScale, float windowYScale) :
Michael Wrightd02c5b62014-02-10 15:10:22 -08004743 seq(nextSeq()),
4744 eventEntry(eventEntry), targetFlags(targetFlags),
Robert Carre07e1032018-11-26 12:55:53 -08004745 xOffset(xOffset), yOffset(yOffset), globalScaleFactor(globalScaleFactor),
4746 windowXScale(windowXScale), windowYScale(windowYScale),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004747 deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
4748 eventEntry->refCount += 1;
4749}
4750
4751InputDispatcher::DispatchEntry::~DispatchEntry() {
4752 eventEntry->release();
4753}
4754
4755uint32_t InputDispatcher::DispatchEntry::nextSeq() {
4756 // Sequence number 0 is reserved and will never be returned.
4757 uint32_t seq;
4758 do {
4759 seq = android_atomic_inc(&sNextSeqAtomic);
4760 } while (!seq);
4761 return seq;
4762}
4763
4764
4765// --- InputDispatcher::InputState ---
4766
4767InputDispatcher::InputState::InputState() {
4768}
4769
4770InputDispatcher::InputState::~InputState() {
4771}
4772
4773bool InputDispatcher::InputState::isNeutral() const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004774 return mKeyMementos.empty() && mMotionMementos.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004775}
4776
4777bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
4778 int32_t displayId) const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004779 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004780 if (memento.deviceId == deviceId
4781 && memento.source == source
4782 && memento.displayId == displayId
4783 && memento.hovering) {
4784 return true;
4785 }
4786 }
4787 return false;
4788}
4789
4790bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
4791 int32_t action, int32_t flags) {
4792 switch (action) {
4793 case AKEY_EVENT_ACTION_UP: {
4794 if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
4795 for (size_t i = 0; i < mFallbackKeys.size(); ) {
4796 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
4797 mFallbackKeys.removeItemsAt(i);
4798 } else {
4799 i += 1;
4800 }
4801 }
4802 }
4803 ssize_t index = findKeyMemento(entry);
4804 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004805 mKeyMementos.erase(mKeyMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004806 return true;
4807 }
4808 /* FIXME: We can't just drop the key up event because that prevents creating
4809 * popup windows that are automatically shown when a key is held and then
4810 * dismissed when the key is released. The problem is that the popup will
4811 * not have received the original key down, so the key up will be considered
4812 * to be inconsistent with its observed state. We could perhaps handle this
4813 * by synthesizing a key down but that will cause other problems.
4814 *
4815 * So for now, allow inconsistent key up events to be dispatched.
4816 *
4817#if DEBUG_OUTBOUND_EVENT_DETAILS
4818 ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
4819 "keyCode=%d, scanCode=%d",
4820 entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
4821#endif
4822 return false;
4823 */
4824 return true;
4825 }
4826
4827 case AKEY_EVENT_ACTION_DOWN: {
4828 ssize_t index = findKeyMemento(entry);
4829 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004830 mKeyMementos.erase(mKeyMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004831 }
4832 addKeyMemento(entry, flags);
4833 return true;
4834 }
4835
4836 default:
4837 return true;
4838 }
4839}
4840
4841bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
4842 int32_t action, int32_t flags) {
4843 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
4844 switch (actionMasked) {
4845 case AMOTION_EVENT_ACTION_UP:
4846 case AMOTION_EVENT_ACTION_CANCEL: {
4847 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4848 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004849 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004850 return true;
4851 }
4852#if DEBUG_OUTBOUND_EVENT_DETAILS
4853 ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004854 "displayId=%" PRId32 ", actionMasked=%d",
4855 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004856#endif
4857 return false;
4858 }
4859
4860 case AMOTION_EVENT_ACTION_DOWN: {
4861 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4862 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004863 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004864 }
4865 addMotionMemento(entry, flags, false /*hovering*/);
4866 return true;
4867 }
4868
4869 case AMOTION_EVENT_ACTION_POINTER_UP:
4870 case AMOTION_EVENT_ACTION_POINTER_DOWN:
4871 case AMOTION_EVENT_ACTION_MOVE: {
Michael Wright38dcdff2014-03-19 12:06:10 -07004872 if (entry->source & AINPUT_SOURCE_CLASS_NAVIGATION) {
4873 // Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need to
4874 // generate cancellation events for these since they're based in relative rather than
4875 // absolute units.
4876 return true;
4877 }
4878
Michael Wrightd02c5b62014-02-10 15:10:22 -08004879 ssize_t index = findMotionMemento(entry, false /*hovering*/);
Michael Wright38dcdff2014-03-19 12:06:10 -07004880
4881 if (entry->source & AINPUT_SOURCE_CLASS_JOYSTICK) {
4882 // Joysticks can send MOVE events without a corresponding DOWN or UP. Since all
4883 // joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral. Any
4884 // other value and we need to track the motion so we can send cancellation events for
4885 // anything generating fallback events (e.g. DPad keys for joystick movements).
4886 if (index >= 0) {
4887 if (entry->pointerCoords[0].isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004888 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wright38dcdff2014-03-19 12:06:10 -07004889 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004890 MotionMemento& memento = mMotionMementos[index];
Michael Wright38dcdff2014-03-19 12:06:10 -07004891 memento.setPointers(entry);
4892 }
4893 } else if (!entry->pointerCoords[0].isEmpty()) {
4894 addMotionMemento(entry, flags, false /*hovering*/);
4895 }
4896
4897 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
4898 return true;
4899 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004900 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004901 MotionMemento& memento = mMotionMementos[index];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004902 memento.setPointers(entry);
4903 return true;
4904 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004905#if DEBUG_OUTBOUND_EVENT_DETAILS
4906 ALOGD("Dropping inconsistent motion pointer up/down or move event: "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004907 "deviceId=%d, source=%08x, displayId=%" PRId32 ", actionMasked=%d",
4908 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004909#endif
4910 return false;
4911 }
4912
4913 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
4914 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4915 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004916 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004917 return true;
4918 }
4919#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004920 ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x, "
4921 "displayId=%" PRId32,
4922 entry->deviceId, entry->source, entry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004923#endif
4924 return false;
4925 }
4926
4927 case AMOTION_EVENT_ACTION_HOVER_ENTER:
4928 case AMOTION_EVENT_ACTION_HOVER_MOVE: {
4929 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4930 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004931 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004932 }
4933 addMotionMemento(entry, flags, true /*hovering*/);
4934 return true;
4935 }
4936
4937 default:
4938 return true;
4939 }
4940}
4941
4942ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
4943 for (size_t i = 0; i < mKeyMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004944 const KeyMemento& memento = mKeyMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004945 if (memento.deviceId == entry->deviceId
4946 && memento.source == entry->source
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004947 && memento.displayId == entry->displayId
Michael Wrightd02c5b62014-02-10 15:10:22 -08004948 && memento.keyCode == entry->keyCode
4949 && memento.scanCode == entry->scanCode) {
4950 return i;
4951 }
4952 }
4953 return -1;
4954}
4955
4956ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
4957 bool hovering) const {
4958 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004959 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004960 if (memento.deviceId == entry->deviceId
4961 && memento.source == entry->source
4962 && memento.displayId == entry->displayId
4963 && memento.hovering == hovering) {
4964 return i;
4965 }
4966 }
4967 return -1;
4968}
4969
4970void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004971 KeyMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004972 memento.deviceId = entry->deviceId;
4973 memento.source = entry->source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004974 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004975 memento.keyCode = entry->keyCode;
4976 memento.scanCode = entry->scanCode;
4977 memento.metaState = entry->metaState;
4978 memento.flags = flags;
4979 memento.downTime = entry->downTime;
4980 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004981 mKeyMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004982}
4983
4984void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
4985 int32_t flags, bool hovering) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004986 MotionMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004987 memento.deviceId = entry->deviceId;
4988 memento.source = entry->source;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004989 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004990 memento.flags = flags;
4991 memento.xPrecision = entry->xPrecision;
4992 memento.yPrecision = entry->yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -07004993 memento.xCursorPosition = entry->xCursorPosition;
4994 memento.yCursorPosition = entry->yCursorPosition;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004995 memento.downTime = entry->downTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004996 memento.setPointers(entry);
4997 memento.hovering = hovering;
4998 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004999 mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005000}
5001
5002void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
5003 pointerCount = entry->pointerCount;
5004 for (uint32_t i = 0; i < entry->pointerCount; i++) {
5005 pointerProperties[i].copyFrom(entry->pointerProperties[i]);
5006 pointerCoords[i].copyFrom(entry->pointerCoords[i]);
5007 }
5008}
5009
5010void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005011 std::vector<EventEntry*>& outEvents, const CancelationOptions& options) {
5012 for (KeyMemento& memento : mKeyMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005013 if (shouldCancelKey(memento, options)) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005014 outEvents.push_back(new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005015 memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08005016 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
5017 memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
5018 }
5019 }
5020
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005021 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005022 if (shouldCancelMotion(memento, options)) {
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08005023 const int32_t action = memento.hovering ?
5024 AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
Garfield Tan00f511d2019-06-12 16:55:40 -07005025 outEvents.push_back(
5026 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, memento.deviceId,
5027 memento.source, memento.displayId, memento.policyFlags, action,
5028 0 /*actionButton*/, memento.flags, AMETA_NONE,
5029 0 /*buttonState*/, MotionClassification::NONE,
5030 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
5031 memento.yPrecision, memento.xCursorPosition,
5032 memento.yCursorPosition, memento.downTime, memento.pointerCount,
5033 memento.pointerProperties, memento.pointerCoords, 0 /*xOffset*/,
5034 0 /*yOffset*/));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005035 }
5036 }
5037}
5038
5039void InputDispatcher::InputState::clear() {
5040 mKeyMementos.clear();
5041 mMotionMementos.clear();
5042 mFallbackKeys.clear();
5043}
5044
5045void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
5046 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005047 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005048 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
5049 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005050 const MotionMemento& otherMemento = other.mMotionMementos[j];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005051 if (memento.deviceId == otherMemento.deviceId
5052 && memento.source == otherMemento.source
5053 && memento.displayId == otherMemento.displayId) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005054 other.mMotionMementos.erase(other.mMotionMementos.begin() + j);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005055 } else {
5056 j += 1;
5057 }
5058 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005059 other.mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005060 }
5061 }
5062}
5063
5064int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
5065 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5066 return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
5067}
5068
5069void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
5070 int32_t fallbackKeyCode) {
5071 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5072 if (index >= 0) {
5073 mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
5074 } else {
5075 mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
5076 }
5077}
5078
5079void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
5080 mFallbackKeys.removeItem(originalKeyCode);
5081}
5082
5083bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
5084 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005085 if (options.keyCode && memento.keyCode != options.keyCode.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005086 return false;
5087 }
5088
Michael Wright3dd60e22019-03-27 22:06:44 +00005089 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5090 return false;
5091 }
5092
5093 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005094 return false;
5095 }
5096
5097 switch (options.mode) {
5098 case CancelationOptions::CANCEL_ALL_EVENTS:
5099 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5100 return true;
5101 case CancelationOptions::CANCEL_FALLBACK_EVENTS:
5102 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
5103 default:
5104 return false;
5105 }
5106}
5107
5108bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
5109 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005110 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5111 return false;
5112 }
5113
5114 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005115 return false;
5116 }
5117
5118 switch (options.mode) {
5119 case CancelationOptions::CANCEL_ALL_EVENTS:
5120 return true;
5121 case CancelationOptions::CANCEL_POINTER_EVENTS:
5122 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
5123 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5124 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
5125 default:
5126 return false;
5127 }
5128}
5129
5130
5131// --- InputDispatcher::Connection ---
5132
Robert Carr803535b2018-08-02 16:38:15 -07005133InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel, bool monitor) :
5134 status(STATUS_NORMAL), inputChannel(inputChannel),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005135 monitor(monitor),
5136 inputPublisher(inputChannel), inputPublisherBlocked(false) {
5137}
5138
5139InputDispatcher::Connection::~Connection() {
5140}
5141
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005142const std::string InputDispatcher::Connection::getWindowName() const {
Robert Carr803535b2018-08-02 16:38:15 -07005143 if (inputChannel != nullptr) {
5144 return inputChannel->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005145 }
5146 if (monitor) {
5147 return "monitor";
5148 }
5149 return "?";
5150}
5151
5152const char* InputDispatcher::Connection::getStatusLabel() const {
5153 switch (status) {
5154 case STATUS_NORMAL:
5155 return "NORMAL";
5156
5157 case STATUS_BROKEN:
5158 return "BROKEN";
5159
5160 case STATUS_ZOMBIE:
5161 return "ZOMBIE";
5162
5163 default:
5164 return "UNKNOWN";
5165 }
5166}
5167
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005168std::deque<InputDispatcher::DispatchEntry*>::iterator
5169InputDispatcher::Connection::findWaitQueueEntry(uint32_t seq) {
5170 for (std::deque<DispatchEntry*>::iterator it = waitQueue.begin(); it != waitQueue.end(); it++) {
5171 if ((*it)->seq == seq) {
5172 return it;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005173 }
5174 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005175 return waitQueue.end();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005176}
5177
Michael Wright3dd60e22019-03-27 22:06:44 +00005178// --- InputDispatcher::Monitor
5179InputDispatcher::Monitor::Monitor(const sp<InputChannel>& inputChannel) :
5180 inputChannel(inputChannel) {
5181}
5182
Michael Wrightd02c5b62014-02-10 15:10:22 -08005183
5184// --- InputDispatcher::CommandEntry ---
Michael Wright3dd60e22019-03-27 22:06:44 +00005185//
Michael Wrightd02c5b62014-02-10 15:10:22 -08005186InputDispatcher::CommandEntry::CommandEntry(Command command) :
Yi Kong9b14ac62018-07-17 13:48:38 -07005187 command(command), eventTime(0), keyEntry(nullptr), userActivityEventType(0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005188 seq(0), handled(false) {
5189}
5190
5191InputDispatcher::CommandEntry::~CommandEntry() {
5192}
5193
Michael Wright3dd60e22019-03-27 22:06:44 +00005194// --- InputDispatcher::TouchedMonitor ---
5195InputDispatcher::TouchedMonitor::TouchedMonitor(const Monitor& monitor, float xOffset,
5196 float yOffset) : monitor(monitor), xOffset(xOffset), yOffset(yOffset) {
5197}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005198
5199// --- InputDispatcher::TouchState ---
5200
5201InputDispatcher::TouchState::TouchState() :
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005202 down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005203}
5204
5205InputDispatcher::TouchState::~TouchState() {
5206}
5207
5208void InputDispatcher::TouchState::reset() {
5209 down = false;
5210 split = false;
5211 deviceId = -1;
5212 source = 0;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005213 displayId = ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005214 windows.clear();
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005215 portalWindows.clear();
Michael Wright3dd60e22019-03-27 22:06:44 +00005216 gestureMonitors.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005217}
5218
5219void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
5220 down = other.down;
5221 split = other.split;
5222 deviceId = other.deviceId;
5223 source = other.source;
5224 displayId = other.displayId;
5225 windows = other.windows;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005226 portalWindows = other.portalWindows;
Michael Wright3dd60e22019-03-27 22:06:44 +00005227 gestureMonitors = other.gestureMonitors;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005228}
5229
5230void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
5231 int32_t targetFlags, BitSet32 pointerIds) {
5232 if (targetFlags & InputTarget::FLAG_SPLIT) {
5233 split = true;
5234 }
5235
5236 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005237 TouchedWindow& touchedWindow = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005238 if (touchedWindow.windowHandle == windowHandle) {
5239 touchedWindow.targetFlags |= targetFlags;
5240 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
5241 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
5242 }
5243 touchedWindow.pointerIds.value |= pointerIds.value;
5244 return;
5245 }
5246 }
5247
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005248 TouchedWindow touchedWindow;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005249 touchedWindow.windowHandle = windowHandle;
5250 touchedWindow.targetFlags = targetFlags;
5251 touchedWindow.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005252 windows.push_back(touchedWindow);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005253}
5254
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005255void InputDispatcher::TouchState::addPortalWindow(const sp<InputWindowHandle>& windowHandle) {
5256 size_t numWindows = portalWindows.size();
5257 for (size_t i = 0; i < numWindows; i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005258 if (portalWindows[i] == windowHandle) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005259 return;
5260 }
5261 }
5262 portalWindows.push_back(windowHandle);
5263}
5264
Michael Wright3dd60e22019-03-27 22:06:44 +00005265void InputDispatcher::TouchState::addGestureMonitors(
5266 const std::vector<TouchedMonitor>& newMonitors) {
5267 const size_t newSize = gestureMonitors.size() + newMonitors.size();
5268 gestureMonitors.reserve(newSize);
5269 gestureMonitors.insert(std::end(gestureMonitors),
5270 std::begin(newMonitors), std::end(newMonitors));
5271}
5272
Michael Wrightd02c5b62014-02-10 15:10:22 -08005273void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
5274 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005275 if (windows[i].windowHandle == windowHandle) {
5276 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005277 return;
5278 }
5279 }
5280}
5281
Robert Carr803535b2018-08-02 16:38:15 -07005282void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) {
5283 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005284 if (windows[i].windowHandle->getToken() == token) {
5285 windows.erase(windows.begin() + i);
Robert Carr803535b2018-08-02 16:38:15 -07005286 return;
5287 }
5288 }
5289}
5290
Michael Wrightd02c5b62014-02-10 15:10:22 -08005291void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
5292 for (size_t i = 0 ; i < windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005293 TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005294 if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
5295 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
5296 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
5297 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
5298 i += 1;
5299 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005300 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005301 }
5302 }
5303}
5304
Michael Wright3dd60e22019-03-27 22:06:44 +00005305void InputDispatcher::TouchState::filterNonMonitors() {
5306 windows.clear();
5307 portalWindows.clear();
5308}
5309
Michael Wrightd02c5b62014-02-10 15:10:22 -08005310sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
5311 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005312 const TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005313 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5314 return window.windowHandle;
5315 }
5316 }
Yi Kong9b14ac62018-07-17 13:48:38 -07005317 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005318}
5319
5320bool InputDispatcher::TouchState::isSlippery() const {
5321 // Must have exactly one foreground window.
5322 bool haveSlipperyForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005323 for (const TouchedWindow& window : windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005324 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5325 if (haveSlipperyForegroundWindow
5326 || !(window.windowHandle->getInfo()->layoutParamsFlags
5327 & InputWindowInfo::FLAG_SLIPPERY)) {
5328 return false;
5329 }
5330 haveSlipperyForegroundWindow = true;
5331 }
5332 }
5333 return haveSlipperyForegroundWindow;
5334}
5335
5336
5337// --- InputDispatcherThread ---
5338
5339InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
5340 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
5341}
5342
5343InputDispatcherThread::~InputDispatcherThread() {
5344}
5345
5346bool InputDispatcherThread::threadLoop() {
5347 mDispatcher->dispatchOnce();
5348 return true;
5349}
5350
5351} // namespace android