blob: c516ab7eed5149327c0ede55a11290d51471e7e7 [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 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700265template <typename K, typename V>
266static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700267 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700268 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800269}
270
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700271/**
272 * Find the entry in std::unordered_map by value, and remove it.
273 * If more than one entry has the same value, then all matching
274 * key-value pairs will be removed.
275 *
276 * Return true if at least one value has been removed.
277 */
278template <typename K, typename V>
279static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
280 bool removed = false;
281 for (auto it = map.begin(); it != map.end();) {
282 if (it->second == value) {
283 it = map.erase(it);
284 removed = true;
285 } else {
286 it++;
287 }
288 }
289 return removed;
290}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800291
292// --- InputDispatcher ---
293
Garfield Tan00f511d2019-06-12 16:55:40 -0700294InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
295 : mPolicy(policy),
296 mPendingEvent(nullptr),
297 mLastDropReason(DROP_REASON_NOT_DROPPED),
298 mAppSwitchSawKeyDown(false),
299 mAppSwitchDueTime(LONG_LONG_MAX),
300 mNextUnblockedEvent(nullptr),
301 mDispatchEnabled(false),
302 mDispatchFrozen(false),
303 mInputFilterEnabled(false),
304 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
305 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800306 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800307 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800308
Yi Kong9b14ac62018-07-17 13:48:38 -0700309 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800310
311 policy->getDispatcherConfiguration(&mConfig);
312}
313
314InputDispatcher::~InputDispatcher() {
315 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800316 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800317
318 resetKeyRepeatLocked();
319 releasePendingEventLocked();
320 drainInboundQueueLocked();
321 }
322
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700323 while (!mConnectionsByFd.empty()) {
324 sp<Connection> connection = mConnectionsByFd.begin()->second;
325 unregisterInputChannel(connection->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800326 }
327}
328
329void InputDispatcher::dispatchOnce() {
330 nsecs_t nextWakeupTime = LONG_LONG_MAX;
331 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800332 std::scoped_lock _l(mLock);
333 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800334
335 // Run a dispatch loop if there are no pending commands.
336 // The dispatch loop might enqueue commands to run afterwards.
337 if (!haveCommandsLocked()) {
338 dispatchOnceInnerLocked(&nextWakeupTime);
339 }
340
341 // Run all pending commands if there are any.
342 // If any commands were run then force the next poll to wake up immediately.
343 if (runCommandsLockedInterruptible()) {
344 nextWakeupTime = LONG_LONG_MIN;
345 }
346 } // release lock
347
348 // Wait for callback or timeout or wake. (make sure we round up, not down)
349 nsecs_t currentTime = now();
350 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
351 mLooper->pollOnce(timeoutMillis);
352}
353
354void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
355 nsecs_t currentTime = now();
356
Jeff Browndc5992e2014-04-11 01:27:26 -0700357 // Reset the key repeat timer whenever normal dispatch is suspended while the
358 // device is in a non-interactive state. This is to ensure that we abort a key
359 // repeat if the device is just coming out of sleep.
360 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800361 resetKeyRepeatLocked();
362 }
363
364 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
365 if (mDispatchFrozen) {
366#if DEBUG_FOCUS
367 ALOGD("Dispatch frozen. Waiting some more.");
368#endif
369 return;
370 }
371
372 // Optimize latency of app switches.
373 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
374 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
375 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
376 if (mAppSwitchDueTime < *nextWakeupTime) {
377 *nextWakeupTime = mAppSwitchDueTime;
378 }
379
380 // Ready to start a new event.
381 // If we don't already have a pending event, go grab one.
382 if (! mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700383 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800384 if (isAppSwitchDue) {
385 // The inbound queue is empty so the app switch key we were waiting
386 // for will never arrive. Stop waiting for it.
387 resetPendingAppSwitchLocked(false);
388 isAppSwitchDue = false;
389 }
390
391 // Synthesize a key repeat if appropriate.
392 if (mKeyRepeatState.lastKeyEntry) {
393 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
394 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
395 } else {
396 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
397 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
398 }
399 }
400 }
401
402 // Nothing to do if there is no pending event.
403 if (!mPendingEvent) {
404 return;
405 }
406 } else {
407 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700408 mPendingEvent = mInboundQueue.front();
409 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800410 traceInboundQueueLengthLocked();
411 }
412
413 // Poke user activity for this event.
414 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
415 pokeUserActivityLocked(mPendingEvent);
416 }
417
418 // Get ready to dispatch the event.
419 resetANRTimeoutsLocked();
420 }
421
422 // Now we have an event to dispatch.
423 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700424 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800425 bool done = false;
426 DropReason dropReason = DROP_REASON_NOT_DROPPED;
427 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
428 dropReason = DROP_REASON_POLICY;
429 } else if (!mDispatchEnabled) {
430 dropReason = DROP_REASON_DISABLED;
431 }
432
433 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700434 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800435 }
436
437 switch (mPendingEvent->type) {
438 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
439 ConfigurationChangedEntry* typedEntry =
440 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
441 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
442 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
443 break;
444 }
445
446 case EventEntry::TYPE_DEVICE_RESET: {
447 DeviceResetEntry* typedEntry =
448 static_cast<DeviceResetEntry*>(mPendingEvent);
449 done = dispatchDeviceResetLocked(currentTime, typedEntry);
450 dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
451 break;
452 }
453
454 case EventEntry::TYPE_KEY: {
455 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
456 if (isAppSwitchDue) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800457 if (isAppSwitchKeyEvent(typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800458 resetPendingAppSwitchLocked(true);
459 isAppSwitchDue = false;
460 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
461 dropReason = DROP_REASON_APP_SWITCH;
462 }
463 }
464 if (dropReason == DROP_REASON_NOT_DROPPED
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800465 && isStaleEvent(currentTime, typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800466 dropReason = DROP_REASON_STALE;
467 }
468 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
469 dropReason = DROP_REASON_BLOCKED;
470 }
471 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
472 break;
473 }
474
475 case EventEntry::TYPE_MOTION: {
476 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
477 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
478 dropReason = DROP_REASON_APP_SWITCH;
479 }
480 if (dropReason == DROP_REASON_NOT_DROPPED
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800481 && isStaleEvent(currentTime, typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800482 dropReason = DROP_REASON_STALE;
483 }
484 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
485 dropReason = DROP_REASON_BLOCKED;
486 }
487 done = dispatchMotionLocked(currentTime, typedEntry,
488 &dropReason, nextWakeupTime);
489 break;
490 }
491
492 default:
493 ALOG_ASSERT(false);
494 break;
495 }
496
497 if (done) {
498 if (dropReason != DROP_REASON_NOT_DROPPED) {
499 dropInboundEventLocked(mPendingEvent, dropReason);
500 }
Michael Wright3a981722015-06-10 15:26:13 +0100501 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800502
503 releasePendingEventLocked();
504 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
505 }
506}
507
508bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700509 bool needWake = mInboundQueue.empty();
510 mInboundQueue.push_back(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800511 traceInboundQueueLengthLocked();
512
513 switch (entry->type) {
514 case EventEntry::TYPE_KEY: {
515 // Optimize app switch latency.
516 // If the application takes too long to catch up then we drop all events preceding
517 // the app switch key.
518 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800519 if (isAppSwitchKeyEvent(keyEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800520 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
521 mAppSwitchSawKeyDown = true;
522 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
523 if (mAppSwitchSawKeyDown) {
524#if DEBUG_APP_SWITCH
525 ALOGD("App switch is pending!");
526#endif
527 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
528 mAppSwitchSawKeyDown = false;
529 needWake = true;
530 }
531 }
532 }
533 break;
534 }
535
536 case EventEntry::TYPE_MOTION: {
537 // Optimize case where the current application is unresponsive and the user
538 // decides to touch a window in a different application.
539 // If the application takes too long to catch up then we drop all events preceding
540 // the touch into the other window.
541 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
542 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
543 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
544 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
Robert Carr740167f2018-10-11 19:03:41 -0700545 && mInputTargetWaitApplicationToken != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800546 int32_t displayId = motionEntry->displayId;
547 int32_t x = int32_t(motionEntry->pointerCoords[0].
548 getAxisValue(AMOTION_EVENT_AXIS_X));
549 int32_t y = int32_t(motionEntry->pointerCoords[0].
550 getAxisValue(AMOTION_EVENT_AXIS_Y));
551 sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
Yi Kong9b14ac62018-07-17 13:48:38 -0700552 if (touchedWindowHandle != nullptr
Robert Carr740167f2018-10-11 19:03:41 -0700553 && touchedWindowHandle->getApplicationToken()
554 != mInputTargetWaitApplicationToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800555 // User touched a different application than the one we are waiting on.
556 // Flag the event, and start pruning the input queue.
557 mNextUnblockedEvent = motionEntry;
558 needWake = true;
559 }
560 }
561 break;
562 }
563 }
564
565 return needWake;
566}
567
568void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
569 entry->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700570 mRecentQueue.push_back(entry);
571 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
572 mRecentQueue.front()->release();
573 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800574 }
575}
576
577sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800578 int32_t x, int32_t y, bool addOutsideTargets, bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800579 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800580 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
581 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800582 const InputWindowInfo* windowInfo = windowHandle->getInfo();
583 if (windowInfo->displayId == displayId) {
584 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800585
586 if (windowInfo->visible) {
587 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
588 bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
589 | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
590 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800591 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
592 if (portalToDisplayId != ADISPLAY_ID_NONE
593 && portalToDisplayId != displayId) {
594 if (addPortalWindows) {
595 // For the monitoring channels of the display.
596 mTempTouchState.addPortalWindow(windowHandle);
597 }
598 return findTouchedWindowAtLocked(
599 portalToDisplayId, x, y, addOutsideTargets, addPortalWindows);
600 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800601 // Found window.
602 return windowHandle;
603 }
604 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800605
606 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
607 mTempTouchState.addOrUpdateWindow(
608 windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE, BitSet32(0));
609 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800610 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800611 }
612 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700613 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800614}
615
Michael Wright3dd60e22019-03-27 22:06:44 +0000616std::vector<InputDispatcher::TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
617 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
618 std::vector<TouchedMonitor> touchedMonitors;
619
620 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
621 addGestureMonitors(monitors, touchedMonitors);
622 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
623 const InputWindowInfo* windowInfo = portalWindow->getInfo();
624 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
625 addGestureMonitors(monitors, touchedMonitors,
626 -windowInfo->frameLeft, -windowInfo->frameTop);
627 }
628 return touchedMonitors;
629}
630
631void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
632 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset, float yOffset) {
633 if (monitors.empty()) {
634 return;
635 }
636 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
637 for (const Monitor& monitor : monitors) {
638 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
639 }
640}
641
Michael Wrightd02c5b62014-02-10 15:10:22 -0800642void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
643 const char* reason;
644 switch (dropReason) {
645 case DROP_REASON_POLICY:
646#if DEBUG_INBOUND_EVENT_DETAILS
647 ALOGD("Dropped event because policy consumed it.");
648#endif
649 reason = "inbound event was dropped because the policy consumed it";
650 break;
651 case DROP_REASON_DISABLED:
Michael Wright3a981722015-06-10 15:26:13 +0100652 if (mLastDropReason != DROP_REASON_DISABLED) {
653 ALOGI("Dropped event because input dispatch is disabled.");
654 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800655 reason = "inbound event was dropped because input dispatch is disabled";
656 break;
657 case DROP_REASON_APP_SWITCH:
658 ALOGI("Dropped event because of pending overdue app switch.");
659 reason = "inbound event was dropped because of pending overdue app switch";
660 break;
661 case DROP_REASON_BLOCKED:
662 ALOGI("Dropped event because the current application is not responding and the user "
663 "has started interacting with a different application.");
664 reason = "inbound event was dropped because the current application is not responding "
665 "and the user has started interacting with a different application";
666 break;
667 case DROP_REASON_STALE:
668 ALOGI("Dropped event because it is stale.");
669 reason = "inbound event was dropped because it is stale";
670 break;
671 default:
672 ALOG_ASSERT(false);
673 return;
674 }
675
676 switch (entry->type) {
677 case EventEntry::TYPE_KEY: {
678 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
679 synthesizeCancelationEventsForAllConnectionsLocked(options);
680 break;
681 }
682 case EventEntry::TYPE_MOTION: {
683 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
684 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
685 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
686 synthesizeCancelationEventsForAllConnectionsLocked(options);
687 } else {
688 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
689 synthesizeCancelationEventsForAllConnectionsLocked(options);
690 }
691 break;
692 }
693 }
694}
695
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800696static bool isAppSwitchKeyCode(int32_t keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800697 return keyCode == AKEYCODE_HOME
698 || keyCode == AKEYCODE_ENDCALL
699 || keyCode == AKEYCODE_APP_SWITCH;
700}
701
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800702bool InputDispatcher::isAppSwitchKeyEvent(KeyEntry* keyEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800703 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
704 && isAppSwitchKeyCode(keyEntry->keyCode)
705 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
706 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
707}
708
709bool InputDispatcher::isAppSwitchPendingLocked() {
710 return mAppSwitchDueTime != LONG_LONG_MAX;
711}
712
713void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
714 mAppSwitchDueTime = LONG_LONG_MAX;
715
716#if DEBUG_APP_SWITCH
717 if (handled) {
718 ALOGD("App switch has arrived.");
719 } else {
720 ALOGD("App switch was abandoned.");
721 }
722#endif
723}
724
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800725bool InputDispatcher::isStaleEvent(nsecs_t currentTime, EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800726 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
727}
728
729bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700730 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800731}
732
733bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700734 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800735 return false;
736 }
737
738 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700739 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700740 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800741 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700742 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800743
744 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700745 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800746 return true;
747}
748
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700749void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
750 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800751}
752
753void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700754 while (!mInboundQueue.empty()) {
755 EventEntry* entry = mInboundQueue.front();
756 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800757 releaseInboundEventLocked(entry);
758 }
759 traceInboundQueueLengthLocked();
760}
761
762void InputDispatcher::releasePendingEventLocked() {
763 if (mPendingEvent) {
764 resetANRTimeoutsLocked();
765 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700766 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800767 }
768}
769
770void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
771 InjectionState* injectionState = entry->injectionState;
772 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
773#if DEBUG_DISPATCH_CYCLE
774 ALOGD("Injected inbound event was dropped.");
775#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800776 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800777 }
778 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700779 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800780 }
781 addRecentEventLocked(entry);
782 entry->release();
783}
784
785void InputDispatcher::resetKeyRepeatLocked() {
786 if (mKeyRepeatState.lastKeyEntry) {
787 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700788 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800789 }
790}
791
792InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
793 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
794
795 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700796 uint32_t policyFlags = entry->policyFlags &
797 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800798 if (entry->refCount == 1) {
799 entry->recycle();
800 entry->eventTime = currentTime;
801 entry->policyFlags = policyFlags;
802 entry->repeatCount += 1;
803 } else {
Prabir Pradhan42611e02018-11-27 14:04:02 -0800804 KeyEntry* newEntry = new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100805 entry->deviceId, entry->source, entry->displayId, policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800806 entry->action, entry->flags, entry->keyCode, entry->scanCode,
807 entry->metaState, entry->repeatCount + 1, entry->downTime);
808
809 mKeyRepeatState.lastKeyEntry = newEntry;
810 entry->release();
811
812 entry = newEntry;
813 }
814 entry->syntheticRepeat = true;
815
816 // Increment reference count since we keep a reference to the event in
817 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
818 entry->refCount += 1;
819
820 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
821 return entry;
822}
823
824bool InputDispatcher::dispatchConfigurationChangedLocked(
825 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
826#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700827 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800828#endif
829
830 // Reset key repeating in case a keyboard device was added or removed or something.
831 resetKeyRepeatLocked();
832
833 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700834 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
835 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800836 commandEntry->eventTime = entry->eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700837 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800838 return true;
839}
840
841bool InputDispatcher::dispatchDeviceResetLocked(
842 nsecs_t currentTime, DeviceResetEntry* entry) {
843#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700844 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
845 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800846#endif
847
848 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
849 "device was reset");
850 options.deviceId = entry->deviceId;
851 synthesizeCancelationEventsForAllConnectionsLocked(options);
852 return true;
853}
854
855bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
856 DropReason* dropReason, nsecs_t* nextWakeupTime) {
857 // Preprocessing.
858 if (! entry->dispatchInProgress) {
859 if (entry->repeatCount == 0
860 && entry->action == AKEY_EVENT_ACTION_DOWN
861 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
862 && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
863 if (mKeyRepeatState.lastKeyEntry
864 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
865 // We have seen two identical key downs in a row which indicates that the device
866 // driver is automatically generating key repeats itself. We take note of the
867 // repeat here, but we disable our own next key repeat timer since it is clear that
868 // we will not need to synthesize key repeats ourselves.
869 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
870 resetKeyRepeatLocked();
871 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
872 } else {
873 // Not a repeat. Save key down state in case we do see a repeat later.
874 resetKeyRepeatLocked();
875 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
876 }
877 mKeyRepeatState.lastKeyEntry = entry;
878 entry->refCount += 1;
879 } else if (! entry->syntheticRepeat) {
880 resetKeyRepeatLocked();
881 }
882
883 if (entry->repeatCount == 1) {
884 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
885 } else {
886 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
887 }
888
889 entry->dispatchInProgress = true;
890
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800891 logOutboundKeyDetails("dispatchKey - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800892 }
893
894 // Handle case where the policy asked us to try again later last time.
895 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
896 if (currentTime < entry->interceptKeyWakeupTime) {
897 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
898 *nextWakeupTime = entry->interceptKeyWakeupTime;
899 }
900 return false; // wait until next wakeup
901 }
902 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
903 entry->interceptKeyWakeupTime = 0;
904 }
905
906 // Give the policy a chance to intercept the key.
907 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
908 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700909 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700910 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +0800911 sp<InputWindowHandle> focusedWindowHandle =
912 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(entry));
913 if (focusedWindowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -0700914 commandEntry->inputChannel =
915 getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800916 }
917 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700918 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800919 entry->refCount += 1;
920 return false; // wait for the command to run
921 } else {
922 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
923 }
924 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
925 if (*dropReason == DROP_REASON_NOT_DROPPED) {
926 *dropReason = DROP_REASON_POLICY;
927 }
928 }
929
930 // Clean up if dropping the event.
931 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800932 setInjectionResult(entry, *dropReason == DROP_REASON_POLICY
Michael Wrightd02c5b62014-02-10 15:10:22 -0800933 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800934 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800935 return true;
936 }
937
938 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800939 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800940 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
941 entry, inputTargets, nextWakeupTime);
942 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
943 return false;
944 }
945
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800946 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800947 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
948 return true;
949 }
950
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800951 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +0000952 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800953
954 // Dispatch the key.
955 dispatchEventLocked(currentTime, entry, inputTargets);
956 return true;
957}
958
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800959void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800960#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100961 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
962 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +0800963 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800964 prefix,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100965 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800966 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Arthur Hung82a4cad2018-11-15 12:10:30 +0800967 entry->repeatCount, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800968#endif
969}
970
971bool InputDispatcher::dispatchMotionLocked(
972 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000973 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800974 // Preprocessing.
975 if (! entry->dispatchInProgress) {
976 entry->dispatchInProgress = true;
977
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800978 logOutboundMotionDetails("dispatchMotion - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800979 }
980
981 // Clean up if dropping the event.
982 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800983 setInjectionResult(entry, *dropReason == DROP_REASON_POLICY
Michael Wrightd02c5b62014-02-10 15:10:22 -0800984 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
985 return true;
986 }
987
988 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
989
990 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800991 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800992
993 bool conflictingPointerActions = false;
994 int32_t injectionResult;
995 if (isPointerEvent) {
996 // Pointer event. (eg. touchscreen)
997 injectionResult = findTouchedWindowTargetsLocked(currentTime,
998 entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
999 } else {
1000 // Non touch event. (eg. trackball)
1001 injectionResult = findFocusedWindowTargetsLocked(currentTime,
1002 entry, inputTargets, nextWakeupTime);
1003 }
1004 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1005 return false;
1006 }
1007
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001008 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001009 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001010 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
1011 CancelationOptions::Mode mode(isPointerEvent ?
1012 CancelationOptions::CANCEL_POINTER_EVENTS :
1013 CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1014 CancelationOptions options(mode, "input event injection failed");
1015 synthesizeCancelationEventsForMonitorsLocked(options);
1016 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001017 return true;
1018 }
1019
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001020 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +00001021 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001022
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001023 if (isPointerEvent) {
1024 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1025 if (stateIndex >= 0) {
1026 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001027 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001028 // The event has gone through these portal windows, so we add monitoring targets of
1029 // the corresponding displays as well.
1030 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001031 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001032 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001033 -windowInfo->frameLeft, -windowInfo->frameTop);
1034 }
1035 }
1036 }
1037 }
1038
Michael Wrightd02c5b62014-02-10 15:10:22 -08001039 // Dispatch the motion.
1040 if (conflictingPointerActions) {
1041 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
1042 "conflicting pointer actions");
1043 synthesizeCancelationEventsForAllConnectionsLocked(options);
1044 }
1045 dispatchEventLocked(currentTime, entry, inputTargets);
1046 return true;
1047}
1048
1049
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001050void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001051#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001052 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1053 ", policyFlags=0x%x, "
Michael Wright7b159c92015-05-14 14:48:03 +01001054 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1055 "metaState=0x%x, buttonState=0x%x,"
Arthur Hung82a4cad2018-11-15 12:10:30 +08001056 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001057 prefix,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001058 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001059 entry->action, entry->actionButton, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001060 entry->metaState, entry->buttonState,
1061 entry->edgeFlags, entry->xPrecision, entry->yPrecision,
Arthur Hung82a4cad2018-11-15 12:10:30 +08001062 entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001063
1064 for (uint32_t i = 0; i < entry->pointerCount; i++) {
1065 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1066 "x=%f, y=%f, pressure=%f, size=%f, "
1067 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001068 "orientation=%f",
Michael Wrightd02c5b62014-02-10 15:10:22 -08001069 i, entry->pointerProperties[i].id,
1070 entry->pointerProperties[i].toolType,
1071 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1072 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1073 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1074 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1075 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1076 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1077 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1078 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001079 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080 }
1081#endif
1082}
1083
1084void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001085 EventEntry* eventEntry, const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001086 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001087#if DEBUG_DISPATCH_CYCLE
1088 ALOGD("dispatchEventToCurrentInputTargets");
1089#endif
1090
1091 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1092
1093 pokeUserActivityLocked(eventEntry);
1094
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001095 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001096 sp<Connection> connection = getConnectionLocked(inputTarget.inputChannel);
1097 if (connection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001098 prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
1099 } else {
1100#if DEBUG_FOCUS
1101 ALOGD("Dropping event delivery to target with channel '%s' because it "
1102 "is no longer registered with the input dispatcher.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001103 inputTarget.inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001104#endif
1105 }
1106 }
1107}
1108
1109int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
1110 const EventEntry* entry,
1111 const sp<InputApplicationHandle>& applicationHandle,
1112 const sp<InputWindowHandle>& windowHandle,
1113 nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001114 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001115 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
1116#if DEBUG_FOCUS
1117 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1118#endif
1119 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1120 mInputTargetWaitStartTime = currentTime;
1121 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1122 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001123 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001124 }
1125 } else {
1126 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1127#if DEBUG_FOCUS
1128 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001129 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130 reason);
1131#endif
1132 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001133 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001134 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001135 } else if (applicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001136 timeout = applicationHandle->getDispatchingTimeout(
1137 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1138 } else {
1139 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1140 }
1141
1142 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1143 mInputTargetWaitStartTime = currentTime;
1144 mInputTargetWaitTimeoutTime = currentTime + timeout;
1145 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001146 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001147
Yi Kong9b14ac62018-07-17 13:48:38 -07001148 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001149 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001150 }
Robert Carr740167f2018-10-11 19:03:41 -07001151 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1152 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001153 }
1154 }
1155 }
1156
1157 if (mInputTargetWaitTimeoutExpired) {
1158 return INPUT_EVENT_INJECTION_TIMED_OUT;
1159 }
1160
1161 if (currentTime >= mInputTargetWaitTimeoutTime) {
1162 onANRLocked(currentTime, applicationHandle, windowHandle,
1163 entry->eventTime, mInputTargetWaitStartTime, reason);
1164
1165 // Force poll loop to wake up immediately on next iteration once we get the
1166 // ANR response back from the policy.
1167 *nextWakeupTime = LONG_LONG_MIN;
1168 return INPUT_EVENT_INJECTION_PENDING;
1169 } else {
1170 // Force poll loop to wake up when timeout is due.
1171 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1172 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1173 }
1174 return INPUT_EVENT_INJECTION_PENDING;
1175 }
1176}
1177
Robert Carr803535b2018-08-02 16:38:15 -07001178void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1179 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1180 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1181 state.removeWindowByToken(token);
1182 }
1183}
1184
Michael Wrightd02c5b62014-02-10 15:10:22 -08001185void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1186 const sp<InputChannel>& inputChannel) {
1187 if (newTimeout > 0) {
1188 // Extend the timeout.
1189 mInputTargetWaitTimeoutTime = now() + newTimeout;
1190 } else {
1191 // Give up.
1192 mInputTargetWaitTimeoutExpired = true;
1193
1194 // Input state will not be realistic. Mark it out of sync.
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001195 sp<Connection> connection = getConnectionLocked(inputChannel);
1196 if (connection != nullptr) {
1197 sp<IBinder> token = connection->inputChannel->getToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001198
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001199 if (token != nullptr) {
1200 removeWindowByTokenLocked(token);
1201 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001202
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001203 if (connection->status == Connection::STATUS_NORMAL) {
1204 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1205 "application not responding");
1206 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001207 }
1208 }
1209 }
1210}
1211
1212nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
1213 nsecs_t currentTime) {
1214 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1215 return currentTime - mInputTargetWaitStartTime;
1216 }
1217 return 0;
1218}
1219
1220void InputDispatcher::resetANRTimeoutsLocked() {
1221#if DEBUG_FOCUS
1222 ALOGD("Resetting ANR timeouts.");
1223#endif
1224
1225 // Reset input target wait timeout.
1226 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001227 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001228}
1229
Tiger Huang721e26f2018-07-24 22:26:19 +08001230/**
1231 * Get the display id that the given event should go to. If this event specifies a valid display id,
1232 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1233 * Focused display is the display that the user most recently interacted with.
1234 */
1235int32_t InputDispatcher::getTargetDisplayId(const EventEntry* entry) {
1236 int32_t displayId;
1237 switch (entry->type) {
1238 case EventEntry::TYPE_KEY: {
1239 const KeyEntry* typedEntry = static_cast<const KeyEntry*>(entry);
1240 displayId = typedEntry->displayId;
1241 break;
1242 }
1243 case EventEntry::TYPE_MOTION: {
1244 const MotionEntry* typedEntry = static_cast<const MotionEntry*>(entry);
1245 displayId = typedEntry->displayId;
1246 break;
1247 }
1248 default: {
1249 ALOGE("Unsupported event type '%" PRId32 "' for target display.", entry->type);
1250 return ADISPLAY_ID_NONE;
1251 }
1252 }
1253 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1254}
1255
Michael Wrightd02c5b62014-02-10 15:10:22 -08001256int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001257 const EventEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001258 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001259 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001260
Tiger Huang721e26f2018-07-24 22:26:19 +08001261 int32_t displayId = getTargetDisplayId(entry);
1262 sp<InputWindowHandle> focusedWindowHandle =
1263 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1264 sp<InputApplicationHandle> focusedApplicationHandle =
1265 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1266
Michael Wrightd02c5b62014-02-10 15:10:22 -08001267 // If there is no currently focused window and no focused application
1268 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001269 if (focusedWindowHandle == nullptr) {
1270 if (focusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001271 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001272 focusedApplicationHandle, nullptr, nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001273 "Waiting because no window has focus but there is a "
1274 "focused application that may eventually add a window "
1275 "when it finishes starting up.");
1276 goto Unresponsive;
1277 }
1278
Arthur Hung3b413f22018-10-26 18:05:34 +08001279 ALOGI("Dropping event because there is no focused window or focused application in display "
1280 "%" PRId32 ".", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001281 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1282 goto Failed;
1283 }
1284
1285 // Check permissions.
Tiger Huang721e26f2018-07-24 22:26:19 +08001286 if (!checkInjectionPermission(focusedWindowHandle, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001287 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1288 goto Failed;
1289 }
1290
Jeff Brownffb49772014-10-10 19:01:34 -07001291 // Check whether the window is ready for more input.
1292 reason = checkWindowReadyForMoreInputLocked(currentTime,
Tiger Huang721e26f2018-07-24 22:26:19 +08001293 focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001294 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001295 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001296 focusedApplicationHandle, focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001297 goto Unresponsive;
1298 }
1299
1300 // Success! Output targets.
1301 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001302 addWindowTargetLocked(focusedWindowHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001303 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
1304 inputTargets);
1305
1306 // Done.
1307Failed:
1308Unresponsive:
1309 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001310 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001311#if DEBUG_FOCUS
1312 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1313 "timeSpentWaitingForApplication=%0.1fms",
1314 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1315#endif
1316 return injectionResult;
1317}
1318
1319int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001320 const MotionEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001321 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001322 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001323 enum InjectionPermission {
1324 INJECTION_PERMISSION_UNKNOWN,
1325 INJECTION_PERMISSION_GRANTED,
1326 INJECTION_PERMISSION_DENIED
1327 };
1328
Michael Wrightd02c5b62014-02-10 15:10:22 -08001329 // For security reasons, we defer updating the touch state until we are sure that
1330 // event injection will be allowed.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001331 int32_t displayId = entry->displayId;
1332 int32_t action = entry->action;
1333 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1334
1335 // Update the touch state as needed based on the properties of the touch event.
1336 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1337 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1338 sp<InputWindowHandle> newHoverWindowHandle;
1339
Jeff Brownf086ddb2014-02-11 14:28:48 -08001340 // Copy current touch state into mTempTouchState.
1341 // This state is always reset at the end of this function, so if we don't find state
1342 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001343 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001344 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1345 if (oldStateIndex >= 0) {
1346 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1347 mTempTouchState.copyFrom(*oldState);
1348 }
1349
1350 bool isSplit = mTempTouchState.split;
1351 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0
1352 && (mTempTouchState.deviceId != entry->deviceId
1353 || mTempTouchState.source != entry->source
1354 || mTempTouchState.displayId != displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001355 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1356 || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1357 || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1358 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
1359 || maskedAction == AMOTION_EVENT_ACTION_SCROLL
1360 || isHoverAction);
Garfield Tan00f511d2019-06-12 16:55:40 -07001361 const bool isFromMouse = entry->source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001362 bool wrongDevice = false;
1363 if (newGesture) {
1364 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001365 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001366#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001367 ALOGD("Dropping event because a pointer for a different device is already down "
1368 "in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001369#endif
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001370 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001371 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1372 switchedDevice = false;
1373 wrongDevice = true;
1374 goto Failed;
1375 }
1376 mTempTouchState.reset();
1377 mTempTouchState.down = down;
1378 mTempTouchState.deviceId = entry->deviceId;
1379 mTempTouchState.source = entry->source;
1380 mTempTouchState.displayId = displayId;
1381 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001382 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
1383#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001384 ALOGI("Dropping move event because a pointer for a different device is already active "
1385 "in display %" PRId32, displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001386#endif
1387 // TODO: test multiple simultaneous input streams.
1388 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1389 switchedDevice = false;
1390 wrongDevice = true;
1391 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001392 }
1393
1394 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1395 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1396
Garfield Tan00f511d2019-06-12 16:55:40 -07001397 int32_t x;
1398 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001399 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001400 // Always dispatch mouse events to cursor position.
1401 if (isFromMouse) {
1402 x = int32_t(entry->xCursorPosition);
1403 y = int32_t(entry->yCursorPosition);
1404 } else {
1405 x = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1406 y = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
1407 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001408 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001409 sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +00001410 displayId, x, y, isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
1411
1412 std::vector<TouchedMonitor> newGestureMonitors = isDown
1413 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1414 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001415
Michael Wrightd02c5b62014-02-10 15:10:22 -08001416 // Figure out whether splitting will be allowed for this window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001417 if (newTouchedWindowHandle != nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001418 && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001419 // New window supports splitting, but we should never split mouse events.
1420 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001421 } else if (isSplit) {
1422 // New window does not support splitting but we have already split events.
1423 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001424 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001425 }
1426
1427 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001428 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001429 // Try to assign the pointer to the first foreground window we find, if there is one.
1430 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001431 }
1432
1433 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1434 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
1435 "(%d, %d) in display %" PRId32 ".", x, y, displayId);
1436 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1437 goto Failed;
1438 }
1439
1440 if (newTouchedWindowHandle != nullptr) {
1441 // Set target flags.
1442 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1443 if (isSplit) {
1444 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001445 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001446 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1447 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1448 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1449 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1450 }
1451
1452 // Update hover state.
1453 if (isHoverAction) {
1454 newHoverWindowHandle = newTouchedWindowHandle;
1455 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1456 newHoverWindowHandle = mLastHoverWindowHandle;
1457 }
1458
1459 // Update the temporary touch state.
1460 BitSet32 pointerIds;
1461 if (isSplit) {
1462 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1463 pointerIds.markBit(pointerId);
1464 }
1465 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001466 }
1467
Michael Wright3dd60e22019-03-27 22:06:44 +00001468 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001469 } else {
1470 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1471
1472 // If the pointer is not currently down, then ignore the event.
1473 if (! mTempTouchState.down) {
1474#if DEBUG_FOCUS
1475 ALOGD("Dropping event because the pointer is not down or we previously "
Arthur Hung3b413f22018-10-26 18:05:34 +08001476 "dropped the pointer down event in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001477#endif
1478 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1479 goto Failed;
1480 }
1481
1482 // Check whether touches should slip outside of the current foreground window.
1483 if (maskedAction == AMOTION_EVENT_ACTION_MOVE
1484 && entry->pointerCount == 1
1485 && mTempTouchState.isSlippery()) {
1486 int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1487 int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
1488
1489 sp<InputWindowHandle> oldTouchedWindowHandle =
1490 mTempTouchState.getFirstForegroundWindowHandle();
1491 sp<InputWindowHandle> newTouchedWindowHandle =
1492 findTouchedWindowAtLocked(displayId, x, y);
1493 if (oldTouchedWindowHandle != newTouchedWindowHandle
Michael Wright3dd60e22019-03-27 22:06:44 +00001494 && oldTouchedWindowHandle != nullptr
Yi Kong9b14ac62018-07-17 13:48:38 -07001495 && newTouchedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001496#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001497 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001498 oldTouchedWindowHandle->getName().c_str(),
Arthur Hung3b413f22018-10-26 18:05:34 +08001499 newTouchedWindowHandle->getName().c_str(),
1500 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001501#endif
1502 // Make a slippery exit from the old window.
1503 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1504 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
1505
1506 // Make a slippery entrance into the new window.
1507 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1508 isSplit = true;
1509 }
1510
1511 int32_t targetFlags = InputTarget::FLAG_FOREGROUND
1512 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
1513 if (isSplit) {
1514 targetFlags |= InputTarget::FLAG_SPLIT;
1515 }
1516 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1517 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1518 }
1519
1520 BitSet32 pointerIds;
1521 if (isSplit) {
1522 pointerIds.markBit(entry->pointerProperties[0].id);
1523 }
1524 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1525 }
1526 }
1527 }
1528
1529 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1530 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001531 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001532#if DEBUG_HOVER
1533 ALOGD("Sending hover exit event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001534 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001535#endif
1536 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1537 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
1538 }
1539
1540 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001541 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001542#if DEBUG_HOVER
1543 ALOGD("Sending hover enter event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001544 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001545#endif
1546 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1547 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
1548 }
1549 }
1550
1551 // Check permission to inject into all touched foreground windows and ensure there
1552 // is at least one touched foreground window.
1553 {
1554 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001555 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001556 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1557 haveForegroundWindow = true;
1558 if (! checkInjectionPermission(touchedWindow.windowHandle,
1559 entry->injectionState)) {
1560 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1561 injectionPermission = INJECTION_PERMISSION_DENIED;
1562 goto Failed;
1563 }
1564 }
1565 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001566 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1567 if (!haveForegroundWindow && !hasGestureMonitor) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001568#if DEBUG_FOCUS
Michael Wright3dd60e22019-03-27 22:06:44 +00001569 ALOGD("Dropping event because there is no touched foreground window in display %"
1570 PRId32 " or gesture monitor to receive it.", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001571#endif
1572 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1573 goto Failed;
1574 }
1575
1576 // Permission granted to injection into all touched foreground windows.
1577 injectionPermission = INJECTION_PERMISSION_GRANTED;
1578 }
1579
1580 // Check whether windows listening for outside touches are owned by the same UID. If it is
1581 // set the policy flag that we will not reveal coordinate information to this window.
1582 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1583 sp<InputWindowHandle> foregroundWindowHandle =
1584 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001585 if (foregroundWindowHandle) {
1586 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1587 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1588 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1589 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1590 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1591 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
1592 InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
1593 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001594 }
1595 }
1596 }
1597 }
1598
1599 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001600 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001601 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001602 // Check whether the window is ready for more input.
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001603 std::string reason = checkWindowReadyForMoreInputLocked(currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001604 touchedWindow.windowHandle, entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001605 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001606 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Yi Kong9b14ac62018-07-17 13:48:38 -07001607 nullptr, touchedWindow.windowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001608 goto Unresponsive;
1609 }
1610 }
1611 }
1612
1613 // If this is the first pointer going down and the touched window has a wallpaper
1614 // then also add the touched wallpaper windows so they are locked in for the duration
1615 // of the touch gesture.
1616 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1617 // engine only supports touch events. We would need to add a mechanism similar
1618 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1619 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1620 sp<InputWindowHandle> foregroundWindowHandle =
1621 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001622 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001623 const std::vector<sp<InputWindowHandle>> windowHandles =
1624 getWindowHandlesLocked(displayId);
1625 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001626 const InputWindowInfo* info = windowHandle->getInfo();
1627 if (info->displayId == displayId
1628 && windowHandle->getInfo()->layoutParamsType
1629 == InputWindowInfo::TYPE_WALLPAPER) {
1630 mTempTouchState.addOrUpdateWindow(windowHandle,
1631 InputTarget::FLAG_WINDOW_IS_OBSCURED
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001632 | InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED
Michael Wrightd02c5b62014-02-10 15:10:22 -08001633 | InputTarget::FLAG_DISPATCH_AS_IS,
1634 BitSet32(0));
1635 }
1636 }
1637 }
1638 }
1639
1640 // Success! Output targets.
1641 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1642
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001643 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001644 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
1645 touchedWindow.pointerIds, inputTargets);
1646 }
1647
Michael Wright3dd60e22019-03-27 22:06:44 +00001648 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1649 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
1650 touchedMonitor.yOffset, inputTargets);
1651 }
1652
Michael Wrightd02c5b62014-02-10 15:10:22 -08001653 // Drop the outside or hover touch windows since we will not care about them
1654 // in the next iteration.
1655 mTempTouchState.filterNonAsIsTouchWindows();
1656
1657Failed:
1658 // Check injection permission once and for all.
1659 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001660 if (checkInjectionPermission(nullptr, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001661 injectionPermission = INJECTION_PERMISSION_GRANTED;
1662 } else {
1663 injectionPermission = INJECTION_PERMISSION_DENIED;
1664 }
1665 }
1666
1667 // Update final pieces of touch state if the injector had permission.
1668 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1669 if (!wrongDevice) {
1670 if (switchedDevice) {
1671#if DEBUG_FOCUS
1672 ALOGD("Conflicting pointer actions: Switched to a different device.");
1673#endif
1674 *outConflictingPointerActions = true;
1675 }
1676
1677 if (isHoverAction) {
1678 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001679 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001680#if DEBUG_FOCUS
1681 ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
1682#endif
1683 *outConflictingPointerActions = true;
1684 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001685 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001686 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1687 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08001688 mTempTouchState.deviceId = entry->deviceId;
1689 mTempTouchState.source = entry->source;
1690 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001691 }
1692 } else if (maskedAction == AMOTION_EVENT_ACTION_UP
1693 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1694 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001695 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001696 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1697 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001698 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001699#if DEBUG_FOCUS
1700 ALOGD("Conflicting pointer actions: Down received while already down.");
1701#endif
1702 *outConflictingPointerActions = true;
1703 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001704 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1705 // One pointer went up.
1706 if (isSplit) {
1707 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1708 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1709
1710 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001711 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001712 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1713 touchedWindow.pointerIds.clearBit(pointerId);
1714 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001715 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001716 continue;
1717 }
1718 }
1719 i += 1;
1720 }
1721 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001722 }
1723
1724 // Save changes unless the action was scroll in which case the temporary touch
1725 // state was only valid for this one action.
1726 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1727 if (mTempTouchState.displayId >= 0) {
1728 if (oldStateIndex >= 0) {
1729 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1730 } else {
1731 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1732 }
1733 } else if (oldStateIndex >= 0) {
1734 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1735 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001736 }
1737
1738 // Update hover state.
1739 mLastHoverWindowHandle = newHoverWindowHandle;
1740 }
1741 } else {
1742#if DEBUG_FOCUS
1743 ALOGD("Not updating touch focus because injection was denied.");
1744#endif
1745 }
1746
1747Unresponsive:
1748 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1749 mTempTouchState.reset();
1750
1751 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001752 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001753#if DEBUG_FOCUS
1754 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1755 "timeSpentWaitingForApplication=%0.1fms",
1756 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1757#endif
1758 return injectionResult;
1759}
1760
1761void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001762 int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets) {
Arthur Hungceeb5d72018-12-05 16:14:18 +08001763 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1764 if (inputChannel == nullptr) {
1765 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1766 return;
1767 }
1768
Michael Wrightd02c5b62014-02-10 15:10:22 -08001769 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001770 InputTarget target;
Arthur Hungceeb5d72018-12-05 16:14:18 +08001771 target.inputChannel = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001772 target.flags = targetFlags;
1773 target.xOffset = - windowInfo->frameLeft;
1774 target.yOffset = - windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08001775 target.globalScaleFactor = windowInfo->globalScaleFactor;
1776 target.windowXScale = windowInfo->windowXScale;
1777 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001778 target.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001779 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001780}
1781
Michael Wright3dd60e22019-03-27 22:06:44 +00001782void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
1783 int32_t displayId, float xOffset, float yOffset) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001784
Michael Wright3dd60e22019-03-27 22:06:44 +00001785 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1786 mGlobalMonitorsByDisplay.find(displayId);
1787
1788 if (it != mGlobalMonitorsByDisplay.end()) {
1789 const std::vector<Monitor>& monitors = it->second;
1790 for (const Monitor& monitor : monitors) {
1791 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001792 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001793 }
1794}
1795
Michael Wright3dd60e22019-03-27 22:06:44 +00001796void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor,
1797 float xOffset, float yOffset, std::vector<InputTarget>& inputTargets) {
1798 InputTarget target;
1799 target.inputChannel = monitor.inputChannel;
1800 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1801 target.xOffset = xOffset;
1802 target.yOffset = yOffset;
1803 target.pointerIds.clear();
1804 target.globalScaleFactor = 1.0f;
1805 inputTargets.push_back(target);
1806}
1807
Michael Wrightd02c5b62014-02-10 15:10:22 -08001808bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
1809 const InjectionState* injectionState) {
1810 if (injectionState
Yi Kong9b14ac62018-07-17 13:48:38 -07001811 && (windowHandle == nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001812 || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
1813 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001814 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001815 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
1816 "owned by uid %d",
1817 injectionState->injectorPid, injectionState->injectorUid,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001818 windowHandle->getName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001819 windowHandle->getInfo()->ownerUid);
1820 } else {
1821 ALOGW("Permission denied: injecting event from pid %d uid %d",
1822 injectionState->injectorPid, injectionState->injectorUid);
1823 }
1824 return false;
1825 }
1826 return true;
1827}
1828
1829bool InputDispatcher::isWindowObscuredAtPointLocked(
1830 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
1831 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001832 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1833 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001834 if (otherHandle == windowHandle) {
1835 break;
1836 }
1837
1838 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1839 if (otherInfo->displayId == displayId
1840 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1841 && otherInfo->frameContainsPoint(x, y)) {
1842 return true;
1843 }
1844 }
1845 return false;
1846}
1847
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001848
1849bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1850 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001851 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001852 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001853 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001854 if (otherHandle == windowHandle) {
1855 break;
1856 }
1857
1858 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1859 if (otherInfo->displayId == displayId
1860 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1861 && otherInfo->overlaps(windowInfo)) {
1862 return true;
1863 }
1864 }
1865 return false;
1866}
1867
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001868std::string InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001869 const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry,
1870 const char* targetType) {
1871 // If the window is paused then keep waiting.
1872 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001873 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001874 }
1875
1876 // If the window's connection is not registered then keep waiting.
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001877 sp<Connection> connection =
1878 getConnectionLocked(getInputChannelLocked(windowHandle->getToken()));
1879 if (connection == nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001880 return StringPrintf("Waiting because the %s window's input channel is not "
Jeff Brownffb49772014-10-10 19:01:34 -07001881 "registered with the input dispatcher. The window may be in the process "
1882 "of being removed.", targetType);
1883 }
1884
1885 // If the connection is dead then keep waiting.
Jeff Brownffb49772014-10-10 19:01:34 -07001886 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001887 return StringPrintf("Waiting because the %s window's input connection is %s."
Jeff Brownffb49772014-10-10 19:01:34 -07001888 "The window may be in the process of being removed.", targetType,
1889 connection->getStatusLabel());
1890 }
1891
1892 // If the connection is backed up then keep waiting.
1893 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001894 return StringPrintf("Waiting because the %s window's input channel is full. "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001895 "Outbound queue length: %zu. Wait queue length: %zu.",
1896 targetType, connection->outboundQueue.size(),
1897 connection->waitQueue.size());
Jeff Brownffb49772014-10-10 19:01:34 -07001898 }
1899
1900 // Ensure that the dispatch queues aren't too far backed up for this event.
1901 if (eventEntry->type == EventEntry::TYPE_KEY) {
1902 // If the event is a key event, then we must wait for all previous events to
1903 // complete before delivering it because previous events may have the
1904 // side-effect of transferring focus to a different window and we want to
1905 // ensure that the following keys are sent to the new window.
1906 //
1907 // Suppose the user touches a button in a window then immediately presses "A".
1908 // If the button causes a pop-up window to appear then we want to ensure that
1909 // the "A" key is delivered to the new pop-up window. This is because users
1910 // often anticipate pending UI changes when typing on a keyboard.
1911 // To obtain this behavior, we must serialize key events with respect to all
1912 // prior input events.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001913 if (!connection->outboundQueue.empty() || !connection->waitQueue.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001914 return StringPrintf("Waiting to send key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001915 "finished processing all of the input events that were previously "
1916 "delivered to it. Outbound queue length: %zu. Wait queue length: "
1917 "%zu.",
1918 targetType, connection->outboundQueue.size(),
1919 connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920 }
Jeff Brownffb49772014-10-10 19:01:34 -07001921 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001922 // Touch events can always be sent to a window immediately because the user intended
1923 // to touch whatever was visible at the time. Even if focus changes or a new
1924 // window appears moments later, the touch event was meant to be delivered to
1925 // whatever window happened to be on screen at the time.
1926 //
1927 // Generic motion events, such as trackball or joystick events are a little trickier.
1928 // Like key events, generic motion events are delivered to the focused window.
1929 // Unlike key events, generic motion events don't tend to transfer focus to other
1930 // windows and it is not important for them to be serialized. So we prefer to deliver
1931 // generic motion events as soon as possible to improve efficiency and reduce lag
1932 // through batching.
1933 //
1934 // The one case where we pause input event delivery is when the wait queue is piling
1935 // up with lots of events because the application is not responding.
1936 // This condition ensures that ANRs are detected reliably.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001937 if (!connection->waitQueue.empty() &&
1938 currentTime >=
1939 connection->waitQueue.front()->deliveryTime + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001940 return StringPrintf("Waiting to send non-key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001941 "finished processing certain input events that were delivered to "
1942 "it over "
1943 "%0.1fms ago. Wait queue length: %zu. Wait queue head age: "
1944 "%0.1fms.",
1945 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
1946 connection->waitQueue.size(),
1947 (currentTime - connection->waitQueue.front()->deliveryTime) *
1948 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001949 }
1950 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001951 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001952}
1953
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001954std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08001955 const sp<InputApplicationHandle>& applicationHandle,
1956 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001957 if (applicationHandle != nullptr) {
1958 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001959 std::string label(applicationHandle->getName());
1960 label += " - ";
1961 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001962 return label;
1963 } else {
1964 return applicationHandle->getName();
1965 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001966 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001967 return windowHandle->getName();
1968 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001969 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001970 }
1971}
1972
1973void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001974 int32_t displayId = getTargetDisplayId(eventEntry);
1975 sp<InputWindowHandle> focusedWindowHandle =
1976 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1977 if (focusedWindowHandle != nullptr) {
1978 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001979 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
1980#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001981 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001982#endif
1983 return;
1984 }
1985 }
1986
1987 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
1988 switch (eventEntry->type) {
1989 case EventEntry::TYPE_MOTION: {
1990 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1991 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1992 return;
1993 }
1994
1995 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
1996 eventType = USER_ACTIVITY_EVENT_TOUCH;
1997 }
1998 break;
1999 }
2000 case EventEntry::TYPE_KEY: {
2001 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
2002 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
2003 return;
2004 }
2005 eventType = USER_ACTIVITY_EVENT_BUTTON;
2006 break;
2007 }
2008 }
2009
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002010 std::unique_ptr<CommandEntry> commandEntry =
2011 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002012 commandEntry->eventTime = eventEntry->eventTime;
2013 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002014 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002015}
2016
2017void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
2018 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002019 if (ATRACE_ENABLED()) {
2020 std::string message = StringPrintf(
2021 "prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2022 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
2023 ATRACE_NAME(message.c_str());
2024 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002025#if DEBUG_DISPATCH_CYCLE
2026 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Robert Carre07e1032018-11-26 12:55:53 -08002027 "xOffset=%f, yOffset=%f, globalScaleFactor=%f, "
2028 "windowScaleFactor=(%f, %f), pointerIds=0x%x",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002029 connection->getInputChannelName().c_str(), inputTarget->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002030 inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08002031 inputTarget->globalScaleFactor,
2032 inputTarget->windowXScale, inputTarget->windowYScale,
2033 inputTarget->pointerIds.value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002034#endif
2035
2036 // Skip this event if the connection status is not normal.
2037 // We don't want to enqueue additional outbound events if the connection is broken.
2038 if (connection->status != Connection::STATUS_NORMAL) {
2039#if DEBUG_DISPATCH_CYCLE
2040 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002041 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002042#endif
2043 return;
2044 }
2045
2046 // Split a motion event if needed.
2047 if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
2048 ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
2049
2050 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
2051 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
2052 MotionEntry* splitMotionEntry = splitMotionEvent(
2053 originalMotionEntry, inputTarget->pointerIds);
2054 if (!splitMotionEntry) {
2055 return; // split event was dropped
2056 }
2057#if DEBUG_FOCUS
2058 ALOGD("channel '%s' ~ Split motion event.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002059 connection->getInputChannelName().c_str());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002060 logOutboundMotionDetails(" ", splitMotionEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002061#endif
2062 enqueueDispatchEntriesLocked(currentTime, connection,
2063 splitMotionEntry, inputTarget);
2064 splitMotionEntry->release();
2065 return;
2066 }
2067 }
2068
2069 // Not splitting. Enqueue dispatch entries for the event as is.
2070 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2071}
2072
2073void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
2074 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002075 if (ATRACE_ENABLED()) {
2076 std::string message = StringPrintf(
2077 "enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2078 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
2079 ATRACE_NAME(message.c_str());
2080 }
2081
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002082 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002083
2084 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002085 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002086 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002087 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002088 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002089 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002090 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002091 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002092 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002093 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002094 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002095 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002096 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
2097
2098 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002099 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002100 startDispatchCycleLocked(currentTime, connection);
2101 }
2102}
2103
chaviw8c9cf542019-03-25 13:02:48 -07002104void InputDispatcher::enqueueDispatchEntryLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002105 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
2106 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002107 if (ATRACE_ENABLED()) {
2108 std::string message = StringPrintf(
2109 "enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2110 connection->getInputChannelName().c_str(),
2111 dispatchModeToString(dispatchMode).c_str());
2112 ATRACE_NAME(message.c_str());
2113 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002114 int32_t inputTargetFlags = inputTarget->flags;
2115 if (!(inputTargetFlags & dispatchMode)) {
2116 return;
2117 }
2118 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2119
2120 // This is a new event.
2121 // Enqueue a new dispatch entry onto the outbound queue for this connection.
2122 DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
2123 inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08002124 inputTarget->globalScaleFactor, inputTarget->windowXScale,
2125 inputTarget->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002126
2127 // Apply target flags and update the connection's input state.
2128 switch (eventEntry->type) {
2129 case EventEntry::TYPE_KEY: {
2130 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2131 dispatchEntry->resolvedAction = keyEntry->action;
2132 dispatchEntry->resolvedFlags = keyEntry->flags;
2133
2134 if (!connection->inputState.trackKey(keyEntry,
2135 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2136#if DEBUG_DISPATCH_CYCLE
2137 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002138 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002139#endif
2140 delete dispatchEntry;
2141 return; // skip the inconsistent event
2142 }
2143 break;
2144 }
2145
2146 case EventEntry::TYPE_MOTION: {
2147 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2148 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2149 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2150 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2151 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2152 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2153 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2154 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2155 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2156 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2157 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2158 } else {
2159 dispatchEntry->resolvedAction = motionEntry->action;
2160 }
2161 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
2162 && !connection->inputState.isHovering(
2163 motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
2164#if DEBUG_DISPATCH_CYCLE
2165 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002166 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002167#endif
2168 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2169 }
2170
2171 dispatchEntry->resolvedFlags = motionEntry->flags;
2172 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2173 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2174 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002175 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2176 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2177 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002178
2179 if (!connection->inputState.trackMotion(motionEntry,
2180 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2181#if DEBUG_DISPATCH_CYCLE
2182 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002183 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002184#endif
2185 delete dispatchEntry;
2186 return; // skip the inconsistent event
2187 }
chaviw8c9cf542019-03-25 13:02:48 -07002188
chaviwfd6d3512019-03-25 13:23:49 -07002189 dispatchPointerDownOutsideFocus(motionEntry->source,
chaviw8c9cf542019-03-25 13:02:48 -07002190 dispatchEntry->resolvedAction, inputTarget->inputChannel->getToken());
2191
Michael Wrightd02c5b62014-02-10 15:10:22 -08002192 break;
2193 }
2194 }
2195
2196 // Remember that we are waiting for this dispatch to complete.
2197 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002198 incrementPendingForegroundDispatches(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002199 }
2200
2201 // Enqueue the dispatch entry.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002202 connection->outboundQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002203 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002204
2205}
2206
chaviwfd6d3512019-03-25 13:23:49 -07002207void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
chaviw8c9cf542019-03-25 13:02:48 -07002208 const sp<IBinder>& newToken) {
2209 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002210 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2211 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002212 return;
2213 }
2214
2215 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2216 if (inputWindowHandle == nullptr) {
2217 return;
2218 }
2219
chaviw8c9cf542019-03-25 13:02:48 -07002220 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002221 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002222
2223 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2224
2225 if (!hasFocusChanged) {
2226 return;
2227 }
2228
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002229 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2230 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002231 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002232 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002233}
2234
2235void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
2236 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002237 if (ATRACE_ENABLED()) {
2238 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
2239 connection->getInputChannelName().c_str());
2240 ATRACE_NAME(message.c_str());
2241 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002242#if DEBUG_DISPATCH_CYCLE
2243 ALOGD("channel '%s' ~ startDispatchCycle",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002244 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002245#endif
2246
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002247 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2248 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002249 dispatchEntry->deliveryTime = currentTime;
2250
2251 // Publish the event.
2252 status_t status;
2253 EventEntry* eventEntry = dispatchEntry->eventEntry;
2254 switch (eventEntry->type) {
2255 case EventEntry::TYPE_KEY: {
2256 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2257
2258 // Publish the key event.
2259 status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002260 keyEntry->deviceId, keyEntry->source, keyEntry->displayId,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002261 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
2262 keyEntry->keyCode, keyEntry->scanCode,
2263 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
2264 keyEntry->eventTime);
2265 break;
2266 }
2267
2268 case EventEntry::TYPE_MOTION: {
2269 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2270
2271 PointerCoords scaledCoords[MAX_POINTERS];
2272 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2273
2274 // Set the X and Y offset depending on the input source.
Siarhei Vishniakou635cb712017-11-01 16:32:14 -07002275 float xOffset, yOffset;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002276 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
2277 && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
Robert Carre07e1032018-11-26 12:55:53 -08002278 float globalScaleFactor = dispatchEntry->globalScaleFactor;
2279 float wxs = dispatchEntry->windowXScale;
2280 float wys = dispatchEntry->windowYScale;
2281 xOffset = dispatchEntry->xOffset * wxs;
2282 yOffset = dispatchEntry->yOffset * wys;
2283 if (wxs != 1.0f || wys != 1.0f || globalScaleFactor != 1.0f) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002284 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002285 scaledCoords[i] = motionEntry->pointerCoords[i];
Robert Carre07e1032018-11-26 12:55:53 -08002286 scaledCoords[i].scale(globalScaleFactor, wxs, wys);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002287 }
2288 usingCoords = scaledCoords;
2289 }
2290 } else {
2291 xOffset = 0.0f;
2292 yOffset = 0.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002293
2294 // We don't want the dispatch target to know.
2295 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002296 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002297 scaledCoords[i].clear();
2298 }
2299 usingCoords = scaledCoords;
2300 }
2301 }
2302
2303 // Publish the motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002304 status =
2305 connection->inputPublisher
2306 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2307 motionEntry->source, motionEntry->displayId,
2308 dispatchEntry->resolvedAction,
2309 motionEntry->actionButton,
2310 dispatchEntry->resolvedFlags,
2311 motionEntry->edgeFlags, motionEntry->metaState,
2312 motionEntry->buttonState,
2313 motionEntry->classification, xOffset, yOffset,
2314 motionEntry->xPrecision, motionEntry->yPrecision,
2315 motionEntry->xCursorPosition,
2316 motionEntry->yCursorPosition, motionEntry->downTime,
2317 motionEntry->eventTime, motionEntry->pointerCount,
2318 motionEntry->pointerProperties, usingCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002319 break;
2320 }
2321
2322 default:
2323 ALOG_ASSERT(false);
2324 return;
2325 }
2326
2327 // Check the result.
2328 if (status) {
2329 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002330 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002331 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
2332 "This is unexpected because the wait queue is empty, so the pipe "
2333 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002334 "event to it, status=%d", connection->getInputChannelName().c_str(),
2335 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002336 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2337 } else {
2338 // Pipe is full and we are waiting for the app to finish process some events
2339 // before sending more events to it.
2340#if DEBUG_DISPATCH_CYCLE
2341 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
2342 "waiting for the application to catch up",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002343 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002344#endif
2345 connection->inputPublisherBlocked = true;
2346 }
2347 } else {
2348 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002349 "status=%d", connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002350 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2351 }
2352 return;
2353 }
2354
2355 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002356 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2357 connection->outboundQueue.end(),
2358 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002359 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002360 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002361 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002362 }
2363}
2364
2365void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
2366 const sp<Connection>& connection, uint32_t seq, bool handled) {
2367#if DEBUG_DISPATCH_CYCLE
2368 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002369 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002370#endif
2371
2372 connection->inputPublisherBlocked = false;
2373
2374 if (connection->status == Connection::STATUS_BROKEN
2375 || connection->status == Connection::STATUS_ZOMBIE) {
2376 return;
2377 }
2378
2379 // Notify other system components and prepare to start the next dispatch cycle.
2380 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2381}
2382
2383void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
2384 const sp<Connection>& connection, bool notify) {
2385#if DEBUG_DISPATCH_CYCLE
2386 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002387 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002388#endif
2389
2390 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002391 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002392 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002393 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002394 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002395
2396 // The connection appears to be unrecoverably broken.
2397 // Ignore already broken or zombie connections.
2398 if (connection->status == Connection::STATUS_NORMAL) {
2399 connection->status = Connection::STATUS_BROKEN;
2400
2401 if (notify) {
2402 // Notify other system components.
2403 onDispatchCycleBrokenLocked(currentTime, connection);
2404 }
2405 }
2406}
2407
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002408void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2409 while (!queue.empty()) {
2410 DispatchEntry* dispatchEntry = queue.front();
2411 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002412 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002413 }
2414}
2415
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002416void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002417 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002418 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002419 }
2420 delete dispatchEntry;
2421}
2422
2423int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2424 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2425
2426 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002427 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002428
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002429 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002430 ALOGE("Received spurious receive callback for unknown input channel. "
2431 "fd=%d, events=0x%x", fd, events);
2432 return 0; // remove the callback
2433 }
2434
2435 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002436 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002437 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2438 if (!(events & ALOOPER_EVENT_INPUT)) {
2439 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002440 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002441 return 1;
2442 }
2443
2444 nsecs_t currentTime = now();
2445 bool gotOne = false;
2446 status_t status;
2447 for (;;) {
2448 uint32_t seq;
2449 bool handled;
2450 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2451 if (status) {
2452 break;
2453 }
2454 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2455 gotOne = true;
2456 }
2457 if (gotOne) {
2458 d->runCommandsLockedInterruptible();
2459 if (status == WOULD_BLOCK) {
2460 return 1;
2461 }
2462 }
2463
2464 notify = status != DEAD_OBJECT || !connection->monitor;
2465 if (notify) {
2466 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002467 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002468 }
2469 } else {
2470 // Monitor channels are never explicitly unregistered.
2471 // We do it automatically when the remote endpoint is closed so don't warn
2472 // about them.
2473 notify = !connection->monitor;
2474 if (notify) {
2475 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002476 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002477 }
2478 }
2479
2480 // Unregister the channel.
2481 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2482 return 0; // remove the callback
2483 } // release lock
2484}
2485
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002486void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked (
Michael Wrightd02c5b62014-02-10 15:10:22 -08002487 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002488 for (const auto& pair : mConnectionsByFd) {
2489 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002490 }
2491}
2492
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002493void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked (
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002494 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002495 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2496 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2497}
2498
2499void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2500 const CancelationOptions& options,
2501 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2502 for (const auto& it : monitorsByDisplay) {
2503 const std::vector<Monitor>& monitors = it.second;
2504 for (const Monitor& monitor : monitors) {
2505 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002506 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002507 }
2508}
2509
Michael Wrightd02c5b62014-02-10 15:10:22 -08002510void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2511 const sp<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002512 sp<Connection> connection = getConnectionLocked(channel);
2513 if (connection == nullptr) {
2514 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002515 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002516
2517 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002518}
2519
2520void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2521 const sp<Connection>& connection, const CancelationOptions& options) {
2522 if (connection->status == Connection::STATUS_BROKEN) {
2523 return;
2524 }
2525
2526 nsecs_t currentTime = now();
2527
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002528 std::vector<EventEntry*> cancelationEvents;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002529 connection->inputState.synthesizeCancelationEvents(currentTime,
2530 cancelationEvents, options);
2531
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002532 if (!cancelationEvents.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002533#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002534 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Michael Wrightd02c5b62014-02-10 15:10:22 -08002535 "with reality: %s, mode=%d.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002536 connection->getInputChannelName().c_str(), cancelationEvents.size(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002537 options.reason, options.mode);
2538#endif
2539 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002540 EventEntry* cancelationEventEntry = cancelationEvents[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002541 switch (cancelationEventEntry->type) {
2542 case EventEntry::TYPE_KEY:
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002543 logOutboundKeyDetails("cancel - ",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002544 static_cast<KeyEntry*>(cancelationEventEntry));
2545 break;
2546 case EventEntry::TYPE_MOTION:
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002547 logOutboundMotionDetails("cancel - ",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002548 static_cast<MotionEntry*>(cancelationEventEntry));
2549 break;
2550 }
2551
2552 InputTarget target;
chaviwfbe5d9c2018-12-26 12:23:37 -08002553 sp<InputWindowHandle> windowHandle = getWindowHandleLocked(
2554 connection->inputChannel->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07002555 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002556 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2557 target.xOffset = -windowInfo->frameLeft;
2558 target.yOffset = -windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08002559 target.globalScaleFactor = windowInfo->globalScaleFactor;
2560 target.windowXScale = windowInfo->windowXScale;
2561 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002562 } else {
2563 target.xOffset = 0;
2564 target.yOffset = 0;
Robert Carre07e1032018-11-26 12:55:53 -08002565 target.globalScaleFactor = 1.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002566 }
2567 target.inputChannel = connection->inputChannel;
2568 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2569
chaviw8c9cf542019-03-25 13:02:48 -07002570 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
Michael Wrightd02c5b62014-02-10 15:10:22 -08002571 &target, InputTarget::FLAG_DISPATCH_AS_IS);
2572
2573 cancelationEventEntry->release();
2574 }
2575
2576 startDispatchCycleLocked(currentTime, connection);
2577 }
2578}
2579
2580InputDispatcher::MotionEntry*
2581InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2582 ALOG_ASSERT(pointerIds.value != 0);
2583
2584 uint32_t splitPointerIndexMap[MAX_POINTERS];
2585 PointerProperties splitPointerProperties[MAX_POINTERS];
2586 PointerCoords splitPointerCoords[MAX_POINTERS];
2587
2588 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2589 uint32_t splitPointerCount = 0;
2590
2591 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2592 originalPointerIndex++) {
2593 const PointerProperties& pointerProperties =
2594 originalMotionEntry->pointerProperties[originalPointerIndex];
2595 uint32_t pointerId = uint32_t(pointerProperties.id);
2596 if (pointerIds.hasBit(pointerId)) {
2597 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2598 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2599 splitPointerCoords[splitPointerCount].copyFrom(
2600 originalMotionEntry->pointerCoords[originalPointerIndex]);
2601 splitPointerCount += 1;
2602 }
2603 }
2604
2605 if (splitPointerCount != pointerIds.count()) {
2606 // This is bad. We are missing some of the pointers that we expected to deliver.
2607 // Most likely this indicates that we received an ACTION_MOVE events that has
2608 // different pointer ids than we expected based on the previous ACTION_DOWN
2609 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2610 // in this way.
2611 ALOGW("Dropping split motion event because the pointer count is %d but "
2612 "we expected there to be %d pointers. This probably means we received "
2613 "a broken sequence of pointer ids from the input device.",
2614 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002615 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002616 }
2617
2618 int32_t action = originalMotionEntry->action;
2619 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2620 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2621 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2622 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2623 const PointerProperties& pointerProperties =
2624 originalMotionEntry->pointerProperties[originalPointerIndex];
2625 uint32_t pointerId = uint32_t(pointerProperties.id);
2626 if (pointerIds.hasBit(pointerId)) {
2627 if (pointerIds.count() == 1) {
2628 // The first/last pointer went down/up.
2629 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2630 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2631 } else {
2632 // A secondary pointer went down/up.
2633 uint32_t splitPointerIndex = 0;
2634 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2635 splitPointerIndex += 1;
2636 }
2637 action = maskedAction | (splitPointerIndex
2638 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2639 }
2640 } else {
2641 // An unrelated pointer changed.
2642 action = AMOTION_EVENT_ACTION_MOVE;
2643 }
2644 }
2645
Garfield Tan00f511d2019-06-12 16:55:40 -07002646 MotionEntry* splitMotionEntry =
2647 new MotionEntry(originalMotionEntry->sequenceNum, originalMotionEntry->eventTime,
2648 originalMotionEntry->deviceId, originalMotionEntry->source,
2649 originalMotionEntry->displayId, originalMotionEntry->policyFlags,
2650 action, originalMotionEntry->actionButton, originalMotionEntry->flags,
2651 originalMotionEntry->metaState, originalMotionEntry->buttonState,
2652 originalMotionEntry->classification, originalMotionEntry->edgeFlags,
2653 originalMotionEntry->xPrecision, originalMotionEntry->yPrecision,
2654 originalMotionEntry->xCursorPosition,
2655 originalMotionEntry->yCursorPosition, originalMotionEntry->downTime,
2656 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002657
2658 if (originalMotionEntry->injectionState) {
2659 splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2660 splitMotionEntry->injectionState->refCount += 1;
2661 }
2662
2663 return splitMotionEntry;
2664}
2665
2666void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2667#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002668 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002669#endif
2670
2671 bool needWake;
2672 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002673 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002674
Prabir Pradhan42611e02018-11-27 14:04:02 -08002675 ConfigurationChangedEntry* newEntry =
2676 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002677 needWake = enqueueInboundEventLocked(newEntry);
2678 } // release lock
2679
2680 if (needWake) {
2681 mLooper->wake();
2682 }
2683}
2684
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002685/**
2686 * If one of the meta shortcuts is detected, process them here:
2687 * Meta + Backspace -> generate BACK
2688 * Meta + Enter -> generate HOME
2689 * This will potentially overwrite keyCode and metaState.
2690 */
2691void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
2692 int32_t& keyCode, int32_t& metaState) {
2693 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2694 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2695 if (keyCode == AKEYCODE_DEL) {
2696 newKeyCode = AKEYCODE_BACK;
2697 } else if (keyCode == AKEYCODE_ENTER) {
2698 newKeyCode = AKEYCODE_HOME;
2699 }
2700 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002701 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002702 struct KeyReplacement replacement = {keyCode, deviceId};
2703 mReplacedKeys.add(replacement, newKeyCode);
2704 keyCode = newKeyCode;
2705 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2706 }
2707 } else if (action == AKEY_EVENT_ACTION_UP) {
2708 // In order to maintain a consistent stream of up and down events, check to see if the key
2709 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2710 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002711 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002712 struct KeyReplacement replacement = {keyCode, deviceId};
2713 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2714 if (index >= 0) {
2715 keyCode = mReplacedKeys.valueAt(index);
2716 mReplacedKeys.removeItemsAt(index);
2717 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2718 }
2719 }
2720}
2721
Michael Wrightd02c5b62014-02-10 15:10:22 -08002722void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2723#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002724 ALOGD("notifyKey - eventTime=%" PRId64
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002725 ", deviceId=%d, source=0x%x, displayId=%" PRId32 "policyFlags=0x%x, action=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +08002726 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002727 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002728 args->action, args->flags, args->keyCode, args->scanCode,
Arthur Hung82a4cad2018-11-15 12:10:30 +08002729 args->metaState, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002730#endif
2731 if (!validateKeyEvent(args->action)) {
2732 return;
2733 }
2734
2735 uint32_t policyFlags = args->policyFlags;
2736 int32_t flags = args->flags;
2737 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002738 // InputDispatcher tracks and generates key repeats on behalf of
2739 // whatever notifies it, so repeatCount should always be set to 0
2740 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002741 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2742 policyFlags |= POLICY_FLAG_VIRTUAL;
2743 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2744 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002745 if (policyFlags & POLICY_FLAG_FUNCTION) {
2746 metaState |= AMETA_FUNCTION_ON;
2747 }
2748
2749 policyFlags |= POLICY_FLAG_TRUSTED;
2750
Michael Wright78f24442014-08-06 15:55:28 -07002751 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002752 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002753
Michael Wrightd02c5b62014-02-10 15:10:22 -08002754 KeyEvent event;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002755 event.initialize(args->deviceId, args->source, args->displayId, args->action,
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002756 flags, keyCode, args->scanCode, metaState, repeatCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002757 args->downTime, args->eventTime);
2758
Michael Wright2b3c3302018-03-02 17:19:13 +00002759 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002760 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002761 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2762 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2763 std::to_string(t.duration().count()).c_str());
2764 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002765
Michael Wrightd02c5b62014-02-10 15:10:22 -08002766 bool needWake;
2767 { // acquire lock
2768 mLock.lock();
2769
2770 if (shouldSendKeyToInputFilterLocked(args)) {
2771 mLock.unlock();
2772
2773 policyFlags |= POLICY_FLAG_FILTERED;
2774 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2775 return; // event was consumed by the filter
2776 }
2777
2778 mLock.lock();
2779 }
2780
Prabir Pradhan42611e02018-11-27 14:04:02 -08002781 KeyEntry* newEntry = new KeyEntry(args->sequenceNum, args->eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002782 args->deviceId, args->source, args->displayId, policyFlags,
Michael Wright78f24442014-08-06 15:55:28 -07002783 args->action, flags, keyCode, args->scanCode,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002784 metaState, repeatCount, args->downTime);
2785
2786 needWake = enqueueInboundEventLocked(newEntry);
2787 mLock.unlock();
2788 } // release lock
2789
2790 if (needWake) {
2791 mLooper->wake();
2792 }
2793}
2794
2795bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2796 return mInputFilterEnabled;
2797}
2798
2799void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2800#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002801 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07002802 ", policyFlags=0x%x, "
2803 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
2804 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07002805 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07002806 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2807 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
2808 args->edgeFlags, args->xPrecision, args->yPrecision, arg->xCursorPosition,
2809 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002810 for (uint32_t i = 0; i < args->pointerCount; i++) {
2811 ALOGD(" Pointer %d: id=%d, toolType=%d, "
2812 "x=%f, y=%f, pressure=%f, size=%f, "
2813 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2814 "orientation=%f",
2815 i, args->pointerProperties[i].id,
2816 args->pointerProperties[i].toolType,
2817 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2818 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2819 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2820 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2821 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2822 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2823 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2824 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2825 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2826 }
2827#endif
Michael Wright7b159c92015-05-14 14:48:03 +01002828 if (!validateMotionEvent(args->action, args->actionButton,
2829 args->pointerCount, args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002830 return;
2831 }
2832
2833 uint32_t policyFlags = args->policyFlags;
2834 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00002835
2836 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002837 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002838 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2839 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2840 std::to_string(t.duration().count()).c_str());
2841 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002842
2843 bool needWake;
2844 { // acquire lock
2845 mLock.lock();
2846
2847 if (shouldSendMotionToInputFilterLocked(args)) {
2848 mLock.unlock();
2849
2850 MotionEvent event;
Garfield Tan00f511d2019-06-12 16:55:40 -07002851 event.initialize(args->deviceId, args->source, args->displayId, args->action,
2852 args->actionButton, args->flags, args->edgeFlags, args->metaState,
2853 args->buttonState, args->classification, 0, 0, args->xPrecision,
2854 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2855 args->downTime, args->eventTime, args->pointerCount,
2856 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002857
2858 policyFlags |= POLICY_FLAG_FILTERED;
2859 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2860 return; // event was consumed by the filter
2861 }
2862
2863 mLock.lock();
2864 }
2865
2866 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002867 MotionEntry* newEntry =
2868 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2869 args->displayId, policyFlags, args->action, args->actionButton,
2870 args->flags, args->metaState, args->buttonState,
2871 args->classification, args->edgeFlags, args->xPrecision,
2872 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2873 args->downTime, args->pointerCount, args->pointerProperties,
2874 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002875
2876 needWake = enqueueInboundEventLocked(newEntry);
2877 mLock.unlock();
2878 } // release lock
2879
2880 if (needWake) {
2881 mLooper->wake();
2882 }
2883}
2884
2885bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08002886 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002887}
2888
2889void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2890#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002891 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
2892 "switchMask=0x%08x",
2893 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002894#endif
2895
2896 uint32_t policyFlags = args->policyFlags;
2897 policyFlags |= POLICY_FLAG_TRUSTED;
2898 mPolicy->notifySwitch(args->eventTime,
2899 args->switchValues, args->switchMask, policyFlags);
2900}
2901
2902void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
2903#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002904 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002905 args->eventTime, args->deviceId);
2906#endif
2907
2908 bool needWake;
2909 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002910 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002911
Prabir Pradhan42611e02018-11-27 14:04:02 -08002912 DeviceResetEntry* newEntry =
2913 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002914 needWake = enqueueInboundEventLocked(newEntry);
2915 } // release lock
2916
2917 if (needWake) {
2918 mLooper->wake();
2919 }
2920}
2921
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002922int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002923 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
2924 uint32_t policyFlags) {
2925#if DEBUG_INBOUND_EVENT_DETAILS
2926 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002927 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2928 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002929#endif
2930
2931 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2932
2933 policyFlags |= POLICY_FLAG_INJECTED;
2934 if (hasInjectionPermission(injectorPid, injectorUid)) {
2935 policyFlags |= POLICY_FLAG_TRUSTED;
2936 }
2937
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07002938 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002939 switch (event->getType()) {
2940 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002941 KeyEvent keyEvent;
2942 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
2943 int32_t action = keyEvent.getAction();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002944 if (! validateKeyEvent(action)) {
2945 return INPUT_EVENT_INJECTION_FAILED;
2946 }
2947
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002948 int32_t flags = keyEvent.getFlags();
2949 int32_t keyCode = keyEvent.getKeyCode();
2950 int32_t metaState = keyEvent.getMetaState();
2951 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
2952 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002953 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002954 action, flags, keyCode, keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002955 keyEvent.getDownTime(), keyEvent.getEventTime());
2956
Michael Wrightd02c5b62014-02-10 15:10:22 -08002957 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2958 policyFlags |= POLICY_FLAG_VIRTUAL;
2959 }
2960
2961 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wright2b3c3302018-03-02 17:19:13 +00002962 android::base::Timer t;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002963 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002964 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2965 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2966 std::to_string(t.duration().count()).c_str());
2967 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002968 }
2969
Michael Wrightd02c5b62014-02-10 15:10:22 -08002970 mLock.lock();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07002971 KeyEntry* injectedEntry =
2972 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
2973 keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
2974 policyFlags, action, flags, keyEvent.getKeyCode(),
2975 keyEvent.getScanCode(), keyEvent.getMetaState(),
2976 keyEvent.getRepeatCount(), keyEvent.getDownTime());
2977 injectedEntries.push(injectedEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002978 break;
2979 }
2980
2981 case AINPUT_EVENT_TYPE_MOTION: {
2982 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002983 int32_t action = motionEvent->getAction();
2984 size_t pointerCount = motionEvent->getPointerCount();
2985 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
Michael Wright7b159c92015-05-14 14:48:03 +01002986 int32_t actionButton = motionEvent->getActionButton();
Charles Chen3611f1f2019-01-29 17:26:18 +08002987 int32_t displayId = motionEvent->getDisplayId();
Michael Wright7b159c92015-05-14 14:48:03 +01002988 if (! validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002989 return INPUT_EVENT_INJECTION_FAILED;
2990 }
2991
2992 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2993 nsecs_t eventTime = motionEvent->getEventTime();
Michael Wright2b3c3302018-03-02 17:19:13 +00002994 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002995 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002996 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2997 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2998 std::to_string(t.duration().count()).c_str());
2999 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003000 }
3001
3002 mLock.lock();
3003 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3004 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003005 MotionEntry* injectedEntry =
Garfield Tan00f511d2019-06-12 16:55:40 -07003006 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(), motionEvent->getRawXCursorPosition(),
3013 motionEvent->getRawYCursorPosition(), motionEvent->getDownTime(),
3014 uint32_t(pointerCount), pointerProperties, samplePointerCoords,
3015 motionEvent->getXOffset(), motionEvent->getYOffset());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003016 injectedEntries.push(injectedEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003017 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3018 sampleEventTimes += 1;
3019 samplePointerCoords += pointerCount;
Garfield Tan00f511d2019-06-12 16:55:40 -07003020 MotionEntry* nextInjectedEntry =
3021 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3022 motionEvent->getDeviceId(), motionEvent->getSource(),
3023 motionEvent->getDisplayId(), policyFlags, action, actionButton,
3024 motionEvent->getFlags(), motionEvent->getMetaState(),
3025 motionEvent->getButtonState(), motionEvent->getClassification(),
3026 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3027 motionEvent->getYPrecision(),
3028 motionEvent->getRawXCursorPosition(),
3029 motionEvent->getRawYCursorPosition(),
3030 motionEvent->getDownTime(), uint32_t(pointerCount),
3031 pointerProperties, samplePointerCoords,
3032 motionEvent->getXOffset(), motionEvent->getYOffset());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003033 injectedEntries.push(nextInjectedEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003034 }
3035 break;
3036 }
3037
3038 default:
3039 ALOGW("Cannot inject event of type %d", event->getType());
3040 return INPUT_EVENT_INJECTION_FAILED;
3041 }
3042
3043 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3044 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3045 injectionState->injectionIsAsync = true;
3046 }
3047
3048 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003049 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003050
3051 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003052 while (!injectedEntries.empty()) {
3053 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3054 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003055 }
3056
3057 mLock.unlock();
3058
3059 if (needWake) {
3060 mLooper->wake();
3061 }
3062
3063 int32_t injectionResult;
3064 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003065 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003066
3067 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3068 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3069 } else {
3070 for (;;) {
3071 injectionResult = injectionState->injectionResult;
3072 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3073 break;
3074 }
3075
3076 nsecs_t remainingTimeout = endTime - now();
3077 if (remainingTimeout <= 0) {
3078#if DEBUG_INJECTION
3079 ALOGD("injectInputEvent - Timed out waiting for injection result "
3080 "to become available.");
3081#endif
3082 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3083 break;
3084 }
3085
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003086 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003087 }
3088
3089 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
3090 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
3091 while (injectionState->pendingForegroundDispatches != 0) {
3092#if DEBUG_INJECTION
3093 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
3094 injectionState->pendingForegroundDispatches);
3095#endif
3096 nsecs_t remainingTimeout = endTime - now();
3097 if (remainingTimeout <= 0) {
3098#if DEBUG_INJECTION
3099 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3100 "dispatches to finish.");
3101#endif
3102 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3103 break;
3104 }
3105
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003106 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003107 }
3108 }
3109 }
3110
3111 injectionState->release();
3112 } // release lock
3113
3114#if DEBUG_INJECTION
3115 ALOGD("injectInputEvent - Finished with result %d. "
3116 "injectorPid=%d, injectorUid=%d",
3117 injectionResult, injectorPid, injectorUid);
3118#endif
3119
3120 return injectionResult;
3121}
3122
3123bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
3124 return injectorUid == 0
3125 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
3126}
3127
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003128void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003129 InjectionState* injectionState = entry->injectionState;
3130 if (injectionState) {
3131#if DEBUG_INJECTION
3132 ALOGD("Setting input event injection result to %d. "
3133 "injectorPid=%d, injectorUid=%d",
3134 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
3135#endif
3136
3137 if (injectionState->injectionIsAsync
3138 && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
3139 // Log the outcome since the injector did not wait for the injection result.
3140 switch (injectionResult) {
3141 case INPUT_EVENT_INJECTION_SUCCEEDED:
3142 ALOGV("Asynchronous input event injection succeeded.");
3143 break;
3144 case INPUT_EVENT_INJECTION_FAILED:
3145 ALOGW("Asynchronous input event injection failed.");
3146 break;
3147 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3148 ALOGW("Asynchronous input event injection permission denied.");
3149 break;
3150 case INPUT_EVENT_INJECTION_TIMED_OUT:
3151 ALOGW("Asynchronous input event injection timed out.");
3152 break;
3153 }
3154 }
3155
3156 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003157 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003158 }
3159}
3160
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003161void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003162 InjectionState* injectionState = entry->injectionState;
3163 if (injectionState) {
3164 injectionState->pendingForegroundDispatches += 1;
3165 }
3166}
3167
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003168void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003169 InjectionState* injectionState = entry->injectionState;
3170 if (injectionState) {
3171 injectionState->pendingForegroundDispatches -= 1;
3172
3173 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003174 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003175 }
3176 }
3177}
3178
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003179std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3180 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003181 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003182}
3183
Michael Wrightd02c5b62014-02-10 15:10:22 -08003184sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003185 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003186 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003187 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3188 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003189 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003190 return windowHandle;
3191 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003192 }
3193 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003194 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003195}
3196
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003197bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003198 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003199 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3200 for (const sp<InputWindowHandle>& handle : windowHandles) {
3201 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003202 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003203 ALOGE("Found window %s in display %" PRId32
3204 ", but it should belong to display %" PRId32,
3205 windowHandle->getName().c_str(), it.first,
3206 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003207 }
3208 return true;
3209 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003210 }
3211 }
3212 return false;
3213}
3214
Robert Carr5c8a0262018-10-03 16:30:44 -07003215sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3216 size_t count = mInputChannelsByToken.count(token);
3217 if (count == 0) {
3218 return nullptr;
3219 }
3220 return mInputChannelsByToken.at(token);
3221}
3222
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003223void InputDispatcher::updateWindowHandlesForDisplayLocked(
3224 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3225 if (inputWindowHandles.empty()) {
3226 // Remove all handles on a display if there are no windows left.
3227 mWindowHandlesByDisplay.erase(displayId);
3228 return;
3229 }
3230
3231 // Since we compare the pointer of input window handles across window updates, we need
3232 // to make sure the handle object for the same window stays unchanged across updates.
3233 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
3234 std::unordered_map<sp<IBinder>, sp<InputWindowHandle>, IBinderHash> oldHandlesByTokens;
3235 for (const sp<InputWindowHandle>& handle : oldHandles) {
3236 oldHandlesByTokens[handle->getToken()] = handle;
3237 }
3238
3239 std::vector<sp<InputWindowHandle>> newHandles;
3240 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3241 if (!handle->updateInfo()) {
3242 // handle no longer valid
3243 continue;
3244 }
3245
3246 const InputWindowInfo* info = handle->getInfo();
3247 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3248 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3249 const bool noInputChannel =
3250 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3251 const bool canReceiveInput =
3252 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3253 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3254 if (canReceiveInput && !noInputChannel) {
3255 ALOGE("Window handle %s has no registered input channel",
3256 handle->getName().c_str());
3257 }
3258 continue;
3259 }
3260
3261 if (info->displayId != displayId) {
3262 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3263 handle->getName().c_str(), displayId, info->displayId);
3264 continue;
3265 }
3266
3267 if (oldHandlesByTokens.find(handle->getToken()) != oldHandlesByTokens.end()) {
3268 const sp<InputWindowHandle> oldHandle = oldHandlesByTokens.at(handle->getToken());
3269 oldHandle->updateFrom(handle);
3270 newHandles.push_back(oldHandle);
3271 } else {
3272 newHandles.push_back(handle);
3273 }
3274 }
3275
3276 // Insert or replace
3277 mWindowHandlesByDisplay[displayId] = newHandles;
3278}
3279
Arthur Hungb92218b2018-08-14 12:00:21 +08003280/**
3281 * Called from InputManagerService, update window handle list by displayId that can receive input.
3282 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3283 * If set an empty list, remove all handles from the specific display.
3284 * For focused handle, check if need to change and send a cancel event to previous one.
3285 * For removed handle, check if need to send a cancel event if already in touch.
3286 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003287void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
chaviw291d88a2019-02-14 10:33:58 -08003288 int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003289#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003290 ALOGD("setInputWindows displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003291#endif
3292 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003293 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003294
Arthur Hungb92218b2018-08-14 12:00:21 +08003295 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003296 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3297 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003298
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003299 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3300
Tiger Huang721e26f2018-07-24 22:26:19 +08003301 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003302 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003303 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3304 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3305 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3306 windowHandle->getInfo()->visible) {
3307 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003308 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003309 if (windowHandle == mLastHoverWindowHandle) {
3310 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003311 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003312 }
3313
3314 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003315 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003316 }
3317
Tiger Huang721e26f2018-07-24 22:26:19 +08003318 sp<InputWindowHandle> oldFocusedWindowHandle =
3319 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3320
3321 if (oldFocusedWindowHandle != newFocusedWindowHandle) {
3322 if (oldFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003323#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003324 ALOGD("Focus left window: %s in display %" PRId32,
3325 oldFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003326#endif
Robert Carr5c8a0262018-10-03 16:30:44 -07003327 sp<InputChannel> focusedInputChannel = getInputChannelLocked(
3328 oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003329 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003330 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3331 "focus left window");
3332 synthesizeCancelationEventsForInputChannelLocked(
3333 focusedInputChannel, options);
3334 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003335 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003336 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003337 if (newFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003338#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003339 ALOGD("Focus entered window: %s in display %" PRId32,
3340 newFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003341#endif
Tiger Huang721e26f2018-07-24 22:26:19 +08003342 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003343 }
Robert Carrf759f162018-11-13 12:57:11 -08003344
3345 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003346 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003347 }
3348
Michael Wrightd02c5b62014-02-10 15:10:22 -08003349 }
3350
Arthur Hungb92218b2018-08-14 12:00:21 +08003351 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3352 if (stateIndex >= 0) {
3353 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Ivan Lozano96f12992017-11-09 14:45:38 -08003354 for (size_t i = 0; i < state.windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003355 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003356 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003357#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003358 ALOGD("Touched window was removed: %s in display %" PRId32,
3359 touchedWindow.windowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003360#endif
Jeff Brownf086ddb2014-02-11 14:28:48 -08003361 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003362 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003363 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003364 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3365 "touched window was removed");
3366 synthesizeCancelationEventsForInputChannelLocked(
3367 touchedInputChannel, options);
3368 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003369 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003370 } else {
3371 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003372 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003373 }
3374 }
3375
3376 // Release information for windows that are no longer present.
3377 // This ensures that unused input channels are released promptly.
3378 // Otherwise, they might stick around until the window handle is destroyed
3379 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003380 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003381 if (!hasWindowHandleLocked(oldWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003382#if DEBUG_FOCUS
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003383 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003384#endif
Arthur Hung3b413f22018-10-26 18:05:34 +08003385 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003386 }
3387 }
3388 } // release lock
3389
3390 // Wake up poll loop since it may need to make new input dispatching choices.
3391 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003392
3393 if (setInputWindowsListener) {
3394 setInputWindowsListener->onSetInputWindowsFinished();
3395 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003396}
3397
3398void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003399 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003400#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003401 ALOGD("setFocusedApplication displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003402#endif
3403 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003404 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003405
Tiger Huang721e26f2018-07-24 22:26:19 +08003406 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3407 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003408 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003409 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3410 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003411 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003412 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003413 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003414 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003415 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003416 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003417 oldFocusedApplicationHandle.clear();
3418 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003419 }
3420
3421#if DEBUG_FOCUS
3422 //logDispatchStateLocked();
3423#endif
3424 } // release lock
3425
3426 // Wake up poll loop since it may need to make new input dispatching choices.
3427 mLooper->wake();
3428}
3429
Tiger Huang721e26f2018-07-24 22:26:19 +08003430/**
3431 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3432 * the display not specified.
3433 *
3434 * We track any unreleased events for each window. If a window loses the ability to receive the
3435 * released event, we will send a cancel event to it. So when the focused display is changed, we
3436 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3437 * display. The display-specified events won't be affected.
3438 */
3439void InputDispatcher::setFocusedDisplay(int32_t displayId) {
3440#if DEBUG_FOCUS
3441 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3442#endif
3443 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003444 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003445
3446 if (mFocusedDisplayId != displayId) {
3447 sp<InputWindowHandle> oldFocusedWindowHandle =
3448 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3449 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003450 sp<InputChannel> inputChannel =
3451 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003452 if (inputChannel != nullptr) {
3453 CancelationOptions options(
Michael Wright3dd60e22019-03-27 22:06:44 +00003454 CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Tiger Huang721e26f2018-07-24 22:26:19 +08003455 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003456 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003457 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3458 }
3459 }
3460 mFocusedDisplayId = displayId;
3461
3462 // Sanity check
3463 sp<InputWindowHandle> newFocusedWindowHandle =
3464 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003465 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003466
Tiger Huang721e26f2018-07-24 22:26:19 +08003467 if (newFocusedWindowHandle == nullptr) {
3468 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3469 if (!mFocusedWindowHandlesByDisplay.empty()) {
3470 ALOGE("But another display has a focused window:");
3471 for (auto& it : mFocusedWindowHandlesByDisplay) {
3472 const int32_t displayId = it.first;
3473 const sp<InputWindowHandle>& windowHandle = it.second;
3474 ALOGE("Display #%" PRId32 " has focused window: '%s'\n",
3475 displayId, windowHandle->getName().c_str());
3476 }
3477 }
3478 }
3479 }
3480
3481#if DEBUG_FOCUS
3482 logDispatchStateLocked();
3483#endif
3484 } // release lock
3485
3486 // Wake up poll loop since it may need to make new input dispatching choices.
3487 mLooper->wake();
3488}
3489
Michael Wrightd02c5b62014-02-10 15:10:22 -08003490void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
3491#if DEBUG_FOCUS
3492 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3493#endif
3494
3495 bool changed;
3496 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003497 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003498
3499 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3500 if (mDispatchFrozen && !frozen) {
3501 resetANRTimeoutsLocked();
3502 }
3503
3504 if (mDispatchEnabled && !enabled) {
3505 resetAndDropEverythingLocked("dispatcher is being disabled");
3506 }
3507
3508 mDispatchEnabled = enabled;
3509 mDispatchFrozen = frozen;
3510 changed = true;
3511 } else {
3512 changed = false;
3513 }
3514
3515#if DEBUG_FOCUS
Tiger Huang721e26f2018-07-24 22:26:19 +08003516 logDispatchStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003517#endif
3518 } // release lock
3519
3520 if (changed) {
3521 // Wake up poll loop since it may need to make new input dispatching choices.
3522 mLooper->wake();
3523 }
3524}
3525
3526void InputDispatcher::setInputFilterEnabled(bool enabled) {
3527#if DEBUG_FOCUS
3528 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3529#endif
3530
3531 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003532 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003533
3534 if (mInputFilterEnabled == enabled) {
3535 return;
3536 }
3537
3538 mInputFilterEnabled = enabled;
3539 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3540 } // release lock
3541
3542 // Wake up poll loop since there might be work to do to drop everything.
3543 mLooper->wake();
3544}
3545
chaviwfbe5d9c2018-12-26 12:23:37 -08003546bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3547 if (fromToken == toToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003548#if DEBUG_FOCUS
chaviwfbe5d9c2018-12-26 12:23:37 -08003549 ALOGD("Trivial transfer to same window.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003550#endif
chaviwfbe5d9c2018-12-26 12:23:37 -08003551 return true;
3552 }
3553
Michael Wrightd02c5b62014-02-10 15:10:22 -08003554 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003555 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003556
chaviwfbe5d9c2018-12-26 12:23:37 -08003557 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3558 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003559 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003560 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003561 return false;
3562 }
chaviw4f2dd402018-12-26 15:30:27 -08003563#if DEBUG_FOCUS
3564 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3565 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3566#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003567 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
3568#if DEBUG_FOCUS
3569 ALOGD("Cannot transfer focus because windows are on different displays.");
3570#endif
3571 return false;
3572 }
3573
3574 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003575 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3576 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3577 for (size_t i = 0; i < state.windows.size(); i++) {
3578 const TouchedWindow& touchedWindow = state.windows[i];
3579 if (touchedWindow.windowHandle == fromWindowHandle) {
3580 int32_t oldTargetFlags = touchedWindow.targetFlags;
3581 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003582
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003583 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003584
Jeff Brownf086ddb2014-02-11 14:28:48 -08003585 int32_t newTargetFlags = oldTargetFlags
3586 & (InputTarget::FLAG_FOREGROUND
3587 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
3588 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003589
Jeff Brownf086ddb2014-02-11 14:28:48 -08003590 found = true;
3591 goto Found;
3592 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003593 }
3594 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003595Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003596
3597 if (! found) {
3598#if DEBUG_FOCUS
3599 ALOGD("Focus transfer failed because from window did not have focus.");
3600#endif
3601 return false;
3602 }
3603
chaviwfbe5d9c2018-12-26 12:23:37 -08003604 sp<InputChannel> fromChannel = getInputChannelLocked(fromToken);
3605 sp<InputChannel> toChannel = getInputChannelLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003606 sp<Connection> fromConnection = getConnectionLocked(fromChannel);
3607 sp<Connection> toConnection = getConnectionLocked(toChannel);
3608 if (fromConnection != nullptr && toConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003609 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
3610 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3611 "transferring touch focus from this window to another window");
3612 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
3613 }
3614
3615#if DEBUG_FOCUS
3616 logDispatchStateLocked();
3617#endif
3618 } // release lock
3619
3620 // Wake up poll loop since it may need to make new input dispatching choices.
3621 mLooper->wake();
3622 return true;
3623}
3624
3625void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
3626#if DEBUG_FOCUS
3627 ALOGD("Resetting and dropping all events (%s).", reason);
3628#endif
3629
3630 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3631 synthesizeCancelationEventsForAllConnectionsLocked(options);
3632
3633 resetKeyRepeatLocked();
3634 releasePendingEventLocked();
3635 drainInboundQueueLocked();
3636 resetANRTimeoutsLocked();
3637
Jeff Brownf086ddb2014-02-11 14:28:48 -08003638 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003639 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003640 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003641}
3642
3643void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003644 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003645 dumpDispatchStateLocked(dump);
3646
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003647 std::istringstream stream(dump);
3648 std::string line;
3649
3650 while (std::getline(stream, line, '\n')) {
3651 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003652 }
3653}
3654
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003655void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003656 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3657 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3658 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003659 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003660
Tiger Huang721e26f2018-07-24 22:26:19 +08003661 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3662 dump += StringPrintf(INDENT "FocusedApplications:\n");
3663 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3664 const int32_t displayId = it.first;
3665 const sp<InputApplicationHandle>& applicationHandle = it.second;
3666 dump += StringPrintf(
3667 INDENT2 "displayId=%" PRId32 ", name='%s', dispatchingTimeout=%0.3fms\n",
3668 displayId,
3669 applicationHandle->getName().c_str(),
3670 applicationHandle->getDispatchingTimeout(
3671 DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
3672 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003673 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003674 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003675 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003676
3677 if (!mFocusedWindowHandlesByDisplay.empty()) {
3678 dump += StringPrintf(INDENT "FocusedWindows:\n");
3679 for (auto& it : mFocusedWindowHandlesByDisplay) {
3680 const int32_t displayId = it.first;
3681 const sp<InputWindowHandle>& windowHandle = it.second;
3682 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n",
3683 displayId, windowHandle->getName().c_str());
3684 }
3685 } else {
3686 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3687 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003688
Jeff Brownf086ddb2014-02-11 14:28:48 -08003689 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003690 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003691 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3692 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003693 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Jeff Brownf086ddb2014-02-11 14:28:48 -08003694 state.displayId, toString(state.down), toString(state.split),
3695 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003696 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003697 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003698 for (size_t i = 0; i < state.windows.size(); i++) {
3699 const TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003700 dump += StringPrintf(INDENT4 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3701 i, touchedWindow.windowHandle->getName().c_str(),
Jeff Brownf086ddb2014-02-11 14:28:48 -08003702 touchedWindow.pointerIds.value,
3703 touchedWindow.targetFlags);
3704 }
3705 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003706 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003707 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003708 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003709 dump += INDENT3 "Portal windows:\n";
3710 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003711 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003712 dump += StringPrintf(INDENT4 "%zu: name='%s'\n",
3713 i, portalWindowHandle->getName().c_str());
3714 }
3715 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003716 }
3717 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003718 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003719 }
3720
Arthur Hungb92218b2018-08-14 12:00:21 +08003721 if (!mWindowHandlesByDisplay.empty()) {
3722 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003723 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003724 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003725 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003726 dump += INDENT2 "Windows:\n";
3727 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003728 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003729 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003730
Arthur Hungb92218b2018-08-14 12:00:21 +08003731 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003732 "portalToDisplayId=%d, paused=%s, hasFocus=%s, hasWallpaper=%s, "
Arthur Hungb92218b2018-08-14 12:00:21 +08003733 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
Riddle Hsu39d4aa52018-11-30 20:46:53 +08003734 "frame=[%d,%d][%d,%d], globalScale=%f, windowScale=(%f,%f), "
Arthur Hungb92218b2018-08-14 12:00:21 +08003735 "touchableRegion=",
3736 i, windowInfo->name.c_str(), windowInfo->displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003737 windowInfo->portalToDisplayId,
Arthur Hungb92218b2018-08-14 12:00:21 +08003738 toString(windowInfo->paused),
3739 toString(windowInfo->hasFocus),
3740 toString(windowInfo->hasWallpaper),
3741 toString(windowInfo->visible),
3742 toString(windowInfo->canReceiveKeys),
3743 windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
3744 windowInfo->layer,
3745 windowInfo->frameLeft, windowInfo->frameTop,
3746 windowInfo->frameRight, windowInfo->frameBottom,
Robert Carre07e1032018-11-26 12:55:53 -08003747 windowInfo->globalScaleFactor,
3748 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003749 dumpRegion(dump, windowInfo->touchableRegion);
3750 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3751 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
3752 windowInfo->ownerPid, windowInfo->ownerUid,
3753 windowInfo->dispatchingTimeout / 1000000.0);
3754 }
3755 } else {
3756 dump += INDENT2 "Windows: <none>\n";
3757 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003758 }
3759 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003760 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003761 }
3762
Michael Wright3dd60e22019-03-27 22:06:44 +00003763 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
3764 for (auto& it : mGlobalMonitorsByDisplay) {
3765 const std::vector<Monitor>& monitors = it.second;
3766 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3767 dumpMonitors(dump, monitors);
3768 }
3769 for (auto& it : mGestureMonitorsByDisplay) {
3770 const std::vector<Monitor>& monitors = it.second;
3771 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
3772 dumpMonitors(dump, monitors);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003773 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003774 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00003775 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003776 }
3777
3778 nsecs_t currentTime = now();
3779
3780 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003781 if (!mRecentQueue.empty()) {
3782 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
3783 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003784 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003785 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003786 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003787 (currentTime - entry->eventTime) * 0.000001f);
3788 }
3789 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003790 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003791 }
3792
3793 // Dump event currently being dispatched.
3794 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003795 dump += INDENT "PendingEvent:\n";
3796 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003797 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003798 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003799 (currentTime - mPendingEvent->eventTime) * 0.000001f);
3800 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003801 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003802 }
3803
3804 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003805 if (!mInboundQueue.empty()) {
3806 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
3807 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003808 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003809 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003810 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003811 (currentTime - entry->eventTime) * 0.000001f);
3812 }
3813 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003814 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003815 }
3816
Michael Wright78f24442014-08-06 15:55:28 -07003817 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003818 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07003819 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
3820 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
3821 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003822 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n",
Michael Wright78f24442014-08-06 15:55:28 -07003823 i, replacement.keyCode, replacement.deviceId, newKeyCode);
3824 }
3825 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003826 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07003827 }
3828
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003829 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003830 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003831 for (const auto& pair : mConnectionsByFd) {
3832 const sp<Connection>& connection = pair.second;
3833 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
3834 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
3835 pair.first, connection->getInputChannelName().c_str(),
3836 connection->getWindowName().c_str(), connection->getStatusLabel(),
3837 toString(connection->monitor),
3838 toString(connection->inputPublisherBlocked));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003839
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003840 if (!connection->outboundQueue.empty()) {
3841 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
3842 connection->outboundQueue.size());
3843 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003844 dump.append(INDENT4);
3845 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003846 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003847 entry->targetFlags, entry->resolvedAction,
3848 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
3849 }
3850 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003851 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003852 }
3853
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003854 if (!connection->waitQueue.empty()) {
3855 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
3856 connection->waitQueue.size());
3857 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003858 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003859 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003860 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003861 "age=%0.1fms, wait=%0.1fms\n",
3862 entry->targetFlags, entry->resolvedAction,
3863 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
3864 (currentTime - entry->deliveryTime) * 0.000001f);
3865 }
3866 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003867 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003868 }
3869 }
3870 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003871 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003872 }
3873
3874 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003875 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003876 (mAppSwitchDueTime - now()) / 1000000.0);
3877 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003878 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003879 }
3880
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003881 dump += INDENT "Configuration:\n";
3882 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003883 mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003884 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003885 mConfig.keyRepeatTimeout * 0.000001f);
3886}
3887
Michael Wright3dd60e22019-03-27 22:06:44 +00003888void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
3889 const size_t numMonitors = monitors.size();
3890 for (size_t i = 0; i < numMonitors; i++) {
3891 const Monitor& monitor = monitors[i];
3892 const sp<InputChannel>& channel = monitor.inputChannel;
3893 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
3894 dump += "\n";
3895 }
3896}
3897
3898status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3899 int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003900#if DEBUG_REGISTRATION
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003901 ALOGD("channel '%s' ~ registerInputChannel - displayId=%" PRId32,
3902 inputChannel->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003903#endif
3904
3905 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003906 std::scoped_lock _l(mLock);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003907 sp<Connection> existingConnection = getConnectionLocked(inputChannel);
3908 if (existingConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003909 ALOGW("Attempted to register already registered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003910 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003911 return BAD_VALUE;
3912 }
3913
Michael Wright3dd60e22019-03-27 22:06:44 +00003914 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003915
3916 int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003917 mConnectionsByFd[fd] = connection;
Robert Carr5c8a0262018-10-03 16:30:44 -07003918 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003919
Michael Wrightd02c5b62014-02-10 15:10:22 -08003920 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3921 } // release lock
3922
3923 // Wake the looper because some connections have changed.
3924 mLooper->wake();
3925 return OK;
3926}
3927
Michael Wright3dd60e22019-03-27 22:06:44 +00003928status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
3929 int32_t displayId, bool isGestureMonitor) {
3930 { // acquire lock
3931 std::scoped_lock _l(mLock);
3932
3933 if (displayId < 0) {
3934 ALOGW("Attempted to register input monitor without a specified display.");
3935 return BAD_VALUE;
3936 }
3937
3938 if (inputChannel->getToken() == nullptr) {
3939 ALOGW("Attempted to register input monitor without an identifying token.");
3940 return BAD_VALUE;
3941 }
3942
3943 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
3944
3945 const int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003946 mConnectionsByFd[fd] = connection;
Michael Wright3dd60e22019-03-27 22:06:44 +00003947 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
3948
3949 auto& monitorsByDisplay = isGestureMonitor
3950 ? mGestureMonitorsByDisplay
3951 : mGlobalMonitorsByDisplay;
3952 monitorsByDisplay[displayId].emplace_back(inputChannel);
3953
3954 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3955
3956 }
3957 // Wake the looper because some connections have changed.
3958 mLooper->wake();
3959 return OK;
3960}
3961
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
3963#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003964 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003965#endif
3966
3967 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003968 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003969
3970 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3971 if (status) {
3972 return status;
3973 }
3974 } // release lock
3975
3976 // Wake the poll loop because removing the connection may have changed the current
3977 // synchronization state.
3978 mLooper->wake();
3979 return OK;
3980}
3981
3982status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
3983 bool notify) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003984 sp<Connection> connection = getConnectionLocked(inputChannel);
3985 if (connection == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003986 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003987 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003988 return BAD_VALUE;
3989 }
3990
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003991 const bool removed = removeByValue(mConnectionsByFd, connection);
3992 ALOG_ASSERT(removed);
Robert Carr5c8a0262018-10-03 16:30:44 -07003993 mInputChannelsByToken.erase(inputChannel->getToken());
3994
Michael Wrightd02c5b62014-02-10 15:10:22 -08003995 if (connection->monitor) {
3996 removeMonitorChannelLocked(inputChannel);
3997 }
3998
3999 mLooper->removeFd(inputChannel->getFd());
4000
4001 nsecs_t currentTime = now();
4002 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4003
4004 connection->status = Connection::STATUS_ZOMBIE;
4005 return OK;
4006}
4007
4008void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004009 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4010 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4011}
4012
4013void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel,
4014 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
4015 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end(); ) {
4016 std::vector<Monitor>& monitors = it->second;
4017 const size_t numMonitors = monitors.size();
4018 for (size_t i = 0; i < numMonitors; i++) {
4019 if (monitors[i].inputChannel == inputChannel) {
4020 monitors.erase(monitors.begin() + i);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004021 break;
4022 }
4023 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004024 if (monitors.empty()) {
4025 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004026 } else {
4027 ++it;
4028 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004029 }
4030}
4031
Michael Wright3dd60e22019-03-27 22:06:44 +00004032status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4033 { // acquire lock
4034 std::scoped_lock _l(mLock);
4035 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4036
4037 if (!foundDisplayId) {
4038 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4039 return BAD_VALUE;
4040 }
4041 int32_t displayId = foundDisplayId.value();
4042
4043 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4044 if (stateIndex < 0) {
4045 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4046 return BAD_VALUE;
4047 }
4048
4049 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4050 std::optional<int32_t> foundDeviceId;
4051 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
4052 if (touchedMonitor.monitor.inputChannel->getToken() == token) {
4053 foundDeviceId = state.deviceId;
4054 }
4055 }
4056 if (!foundDeviceId || !state.down) {
4057 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
4058 " Ignoring.");
4059 return BAD_VALUE;
4060 }
4061 int32_t deviceId = foundDeviceId.value();
4062
4063 // Send cancel events to all the input channels we're stealing from.
4064 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4065 "gesture monitor stole pointer stream");
4066 options.deviceId = deviceId;
4067 options.displayId = displayId;
4068 for (const TouchedWindow& window : state.windows) {
4069 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
4070 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4071 }
4072 // Then clear the current touch state so we stop dispatching to them as well.
4073 state.filterNonMonitors();
4074 }
4075 return OK;
4076}
4077
4078
4079std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4080 const sp<IBinder>& token) {
4081 for (const auto& it : mGestureMonitorsByDisplay) {
4082 const std::vector<Monitor>& monitors = it.second;
4083 for (const Monitor& monitor : monitors) {
4084 if (monitor.inputChannel->getToken() == token) {
4085 return it.first;
4086 }
4087 }
4088 }
4089 return std::nullopt;
4090}
4091
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004092sp<InputDispatcher::Connection> InputDispatcher::getConnectionLocked(
4093 const sp<InputChannel>& inputChannel) {
Robert Carr4e670e52018-08-15 13:26:12 -07004094 if (inputChannel == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004095 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004096 }
4097
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004098 for (const auto& pair : mConnectionsByFd) {
4099 sp<Connection> connection = pair.second;
Robert Carr4e670e52018-08-15 13:26:12 -07004100 if (connection->inputChannel->getToken() == inputChannel->getToken()) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004101 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004102 }
4103 }
Robert Carr4e670e52018-08-15 13:26:12 -07004104
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004105 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004106}
4107
4108void InputDispatcher::onDispatchCycleFinishedLocked(
4109 nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004110 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4111 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004112 commandEntry->connection = connection;
4113 commandEntry->eventTime = currentTime;
4114 commandEntry->seq = seq;
4115 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004116 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004117}
4118
4119void InputDispatcher::onDispatchCycleBrokenLocked(
4120 nsecs_t currentTime, const sp<Connection>& connection) {
4121 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004122 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004123
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004124 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4125 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004126 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004127 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004128}
4129
chaviw0c06c6e2019-01-09 13:27:07 -08004130void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
4131 const sp<InputWindowHandle>& newFocus) {
4132 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4133 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004134 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4135 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004136 commandEntry->oldToken = oldToken;
4137 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004138 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004139}
4140
Michael Wrightd02c5b62014-02-10 15:10:22 -08004141void InputDispatcher::onANRLocked(
4142 nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
4143 const sp<InputWindowHandle>& windowHandle,
4144 nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
4145 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4146 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4147 ALOGI("Application is not responding: %s. "
4148 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004149 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004150 dispatchLatency, waitDuration, reason);
4151
4152 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004153 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004154 struct tm tm;
4155 localtime_r(&t, &tm);
4156 char timestr[64];
4157 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4158 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004159 mLastANRState += INDENT "ANR:\n";
4160 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
4161 mLastANRState += StringPrintf(INDENT2 "Window: %s\n",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004162 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004163 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4164 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4165 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004166 dumpDispatchStateLocked(mLastANRState);
4167
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004168 std::unique_ptr<CommandEntry> commandEntry =
4169 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004170 commandEntry->inputApplicationHandle = applicationHandle;
Robert Carr5c8a0262018-10-03 16:30:44 -07004171 commandEntry->inputChannel = windowHandle != nullptr ?
4172 getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004173 commandEntry->reason = reason;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004174 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004175}
4176
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004177void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible (
Michael Wrightd02c5b62014-02-10 15:10:22 -08004178 CommandEntry* commandEntry) {
4179 mLock.unlock();
4180
4181 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4182
4183 mLock.lock();
4184}
4185
4186void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
4187 CommandEntry* commandEntry) {
4188 sp<Connection> connection = commandEntry->connection;
4189
4190 if (connection->status != Connection::STATUS_ZOMBIE) {
4191 mLock.unlock();
4192
Robert Carr803535b2018-08-02 16:38:15 -07004193 mPolicy->notifyInputChannelBroken(connection->inputChannel->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004194
4195 mLock.lock();
4196 }
4197}
4198
Robert Carrf759f162018-11-13 12:57:11 -08004199void InputDispatcher::doNotifyFocusChangedLockedInterruptible(
4200 CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004201 sp<IBinder> oldToken = commandEntry->oldToken;
4202 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004203 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004204 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004205 mLock.lock();
4206}
4207
Michael Wrightd02c5b62014-02-10 15:10:22 -08004208void InputDispatcher::doNotifyANRLockedInterruptible(
4209 CommandEntry* commandEntry) {
4210 mLock.unlock();
4211
4212 nsecs_t newTimeout = mPolicy->notifyANR(
Robert Carr803535b2018-08-02 16:38:15 -07004213 commandEntry->inputApplicationHandle,
4214 commandEntry->inputChannel ? commandEntry->inputChannel->getToken() : nullptr,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004215 commandEntry->reason);
4216
4217 mLock.lock();
4218
4219 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
Robert Carr803535b2018-08-02 16:38:15 -07004220 commandEntry->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004221}
4222
4223void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4224 CommandEntry* commandEntry) {
4225 KeyEntry* entry = commandEntry->keyEntry;
4226
4227 KeyEvent event;
4228 initializeKeyEvent(&event, entry);
4229
4230 mLock.unlock();
4231
Michael Wright2b3c3302018-03-02 17:19:13 +00004232 android::base::Timer t;
Robert Carr803535b2018-08-02 16:38:15 -07004233 sp<IBinder> token = commandEntry->inputChannel != nullptr ?
4234 commandEntry->inputChannel->getToken() : nullptr;
4235 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004236 &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004237 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4238 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
4239 std::to_string(t.duration().count()).c_str());
4240 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004241
4242 mLock.lock();
4243
4244 if (delay < 0) {
4245 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4246 } else if (!delay) {
4247 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4248 } else {
4249 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4250 entry->interceptKeyWakeupTime = now() + delay;
4251 }
4252 entry->release();
4253}
4254
chaviwfd6d3512019-03-25 13:23:49 -07004255void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4256 mLock.unlock();
4257 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4258 mLock.lock();
4259}
4260
Michael Wrightd02c5b62014-02-10 15:10:22 -08004261void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
4262 CommandEntry* commandEntry) {
4263 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004264 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004265 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004266 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004267
4268 // Handle post-event policy actions.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004269 std::deque<InputDispatcher::DispatchEntry*>::iterator dispatchEntryIt =
4270 connection->findWaitQueueEntry(seq);
4271 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004272 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004273 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004274 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004275
4276 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4277 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4278 std::string msg =
4279 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4280 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4281 dispatchEntry->eventEntry->appendDescription(msg);
4282 ALOGI("%s", msg.c_str());
4283 }
4284
4285 bool restartEvent;
4286 if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
4287 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4288 restartEvent =
4289 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
4290 } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
4291 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4292 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4293 handled);
4294 } else {
4295 restartEvent = false;
4296 }
4297
4298 // Dequeue the event and start the next cycle.
4299 // Note that because the lock might have been released, it is possible that the
4300 // contents of the wait queue to have been drained, so we need to double-check
4301 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004302 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4303 if (dispatchEntryIt != connection->waitQueue.end()) {
4304 dispatchEntry = *dispatchEntryIt;
4305 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004306 traceWaitQueueLength(connection);
4307 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004308 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004309 traceOutboundQueueLength(connection);
4310 } else {
4311 releaseDispatchEntry(dispatchEntry);
4312 }
4313 }
4314
4315 // Start the next dispatch cycle for this connection.
4316 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004317}
4318
4319bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
4320 DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004321 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004322 if (!handled) {
4323 // Report the key as unhandled, since the fallback was not handled.
4324 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4325 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004326 return false;
4327 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004328
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004329 // Get the fallback key state.
4330 // Clear it out after dispatching the UP.
4331 int32_t originalKeyCode = keyEntry->keyCode;
4332 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4333 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4334 connection->inputState.removeFallbackKey(originalKeyCode);
4335 }
4336
4337 if (handled || !dispatchEntry->hasForegroundTarget()) {
4338 // If the application handles the original key for which we previously
4339 // generated a fallback or if the window is not a foreground window,
4340 // then cancel the associated fallback key, if any.
4341 if (fallbackKeyCode != -1) {
4342 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004343#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004344 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004345 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4346 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4347 keyEntry->policyFlags);
4348#endif
4349 KeyEvent event;
4350 initializeKeyEvent(&event, keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004351 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004352
4353 mLock.unlock();
4354
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004355 mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4356 &event, keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004357
4358 mLock.lock();
4359
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004360 // Cancel the fallback key.
4361 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004362 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004363 "application handled the original non-fallback key "
4364 "or is no longer a foreground target, "
4365 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004366 options.keyCode = fallbackKeyCode;
4367 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004368 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004369 connection->inputState.removeFallbackKey(originalKeyCode);
4370 }
4371 } else {
4372 // If the application did not handle a non-fallback key, first check
4373 // that we are in a good state to perform unhandled key event processing
4374 // Then ask the policy what to do with it.
4375 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
4376 && keyEntry->repeatCount == 0;
4377 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004378#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004379 ALOGD("Unhandled key event: Skipping unhandled key event processing "
4380 "since this is not an initial down. "
4381 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4382 originalKeyCode, keyEntry->action, keyEntry->repeatCount,
4383 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004384#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004385 return false;
4386 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004387
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004388 // Dispatch the unhandled key to the policy.
4389#if DEBUG_OUTBOUND_EVENT_DETAILS
4390 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
4391 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4392 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4393 keyEntry->policyFlags);
4394#endif
4395 KeyEvent event;
4396 initializeKeyEvent(&event, keyEntry);
4397
4398 mLock.unlock();
4399
4400 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4401 &event, keyEntry->policyFlags, &event);
4402
4403 mLock.lock();
4404
4405 if (connection->status != Connection::STATUS_NORMAL) {
4406 connection->inputState.removeFallbackKey(originalKeyCode);
4407 return false;
4408 }
4409
4410 // Latch the fallback keycode for this key on an initial down.
4411 // The fallback keycode cannot change at any other point in the lifecycle.
4412 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004413 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004414 fallbackKeyCode = event.getKeyCode();
4415 } else {
4416 fallbackKeyCode = AKEYCODE_UNKNOWN;
4417 }
4418 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4419 }
4420
4421 ALOG_ASSERT(fallbackKeyCode != -1);
4422
4423 // Cancel the fallback key if the policy decides not to send it anymore.
4424 // We will continue to dispatch the key to the policy but we will no
4425 // longer dispatch a fallback key to the application.
4426 if (fallbackKeyCode != AKEYCODE_UNKNOWN
4427 && (!fallback || fallbackKeyCode != event.getKeyCode())) {
4428#if DEBUG_OUTBOUND_EVENT_DETAILS
4429 if (fallback) {
4430 ALOGD("Unhandled key event: Policy requested to send key %d"
4431 "as a fallback for %d, but on the DOWN it had requested "
4432 "to send %d instead. Fallback canceled.",
4433 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
4434 } else {
4435 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
4436 "but on the DOWN it had requested to send %d. "
4437 "Fallback canceled.",
4438 originalKeyCode, fallbackKeyCode);
4439 }
4440#endif
4441
4442 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4443 "canceling fallback, policy no longer desires it");
4444 options.keyCode = fallbackKeyCode;
4445 synthesizeCancelationEventsForConnectionLocked(connection, options);
4446
4447 fallback = false;
4448 fallbackKeyCode = AKEYCODE_UNKNOWN;
4449 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
4450 connection->inputState.setFallbackKey(originalKeyCode,
4451 fallbackKeyCode);
4452 }
4453 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004454
4455#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004456 {
4457 std::string msg;
4458 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4459 connection->inputState.getFallbackKeys();
4460 for (size_t i = 0; i < fallbackKeys.size(); i++) {
4461 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i),
4462 fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004463 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004464 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
4465 fallbackKeys.size(), msg.c_str());
4466 }
4467#endif
4468
4469 if (fallback) {
4470 // Restart the dispatch cycle using the fallback key.
4471 keyEntry->eventTime = event.getEventTime();
4472 keyEntry->deviceId = event.getDeviceId();
4473 keyEntry->source = event.getSource();
4474 keyEntry->displayId = event.getDisplayId();
4475 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4476 keyEntry->keyCode = fallbackKeyCode;
4477 keyEntry->scanCode = event.getScanCode();
4478 keyEntry->metaState = event.getMetaState();
4479 keyEntry->repeatCount = event.getRepeatCount();
4480 keyEntry->downTime = event.getDownTime();
4481 keyEntry->syntheticRepeat = false;
4482
4483#if DEBUG_OUTBOUND_EVENT_DETAILS
4484 ALOGD("Unhandled key event: Dispatching fallback key. "
4485 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4486 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
4487#endif
4488 return true; // restart the event
4489 } else {
4490#if DEBUG_OUTBOUND_EVENT_DETAILS
4491 ALOGD("Unhandled key event: No fallback key.");
4492#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004493
4494 // Report the key as unhandled, since there is no fallback key.
4495 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004496 }
4497 }
4498 return false;
4499}
4500
4501bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
4502 DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
4503 return false;
4504}
4505
4506void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4507 mLock.unlock();
4508
4509 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4510
4511 mLock.lock();
4512}
4513
4514void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004515 event->initialize(entry->deviceId, entry->source, entry->displayId, entry->action, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004516 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
4517 entry->downTime, entry->eventTime);
4518}
4519
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004520void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry* entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004521 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
4522 // TODO Write some statistics about how long we spend waiting.
4523}
4524
4525void InputDispatcher::traceInboundQueueLengthLocked() {
4526 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004527 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004528 }
4529}
4530
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004531void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004532 if (ATRACE_ENABLED()) {
4533 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004534 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004535 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004536 }
4537}
4538
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004539void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004540 if (ATRACE_ENABLED()) {
4541 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004542 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004543 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004544 }
4545}
4546
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004547void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004548 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004549
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004550 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004551 dumpDispatchStateLocked(dump);
4552
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004553 if (!mLastANRState.empty()) {
4554 dump += "\nInput Dispatcher State at time of last ANR:\n";
4555 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004556 }
4557}
4558
4559void InputDispatcher::monitor() {
4560 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004561 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004562 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004563 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004564}
4565
4566
Michael Wrightd02c5b62014-02-10 15:10:22 -08004567// --- InputDispatcher::InjectionState ---
4568
4569InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
4570 refCount(1),
4571 injectorPid(injectorPid), injectorUid(injectorUid),
4572 injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
4573 pendingForegroundDispatches(0) {
4574}
4575
4576InputDispatcher::InjectionState::~InjectionState() {
4577}
4578
4579void InputDispatcher::InjectionState::release() {
4580 refCount -= 1;
4581 if (refCount == 0) {
4582 delete this;
4583 } else {
4584 ALOG_ASSERT(refCount > 0);
4585 }
4586}
4587
4588
4589// --- InputDispatcher::EventEntry ---
4590
Prabir Pradhan42611e02018-11-27 14:04:02 -08004591InputDispatcher::EventEntry::EventEntry(uint32_t sequenceNum, int32_t type,
4592 nsecs_t eventTime, uint32_t policyFlags) :
4593 sequenceNum(sequenceNum), refCount(1), type(type), eventTime(eventTime),
4594 policyFlags(policyFlags), injectionState(nullptr), dispatchInProgress(false) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004595}
4596
4597InputDispatcher::EventEntry::~EventEntry() {
4598 releaseInjectionState();
4599}
4600
4601void InputDispatcher::EventEntry::release() {
4602 refCount -= 1;
4603 if (refCount == 0) {
4604 delete this;
4605 } else {
4606 ALOG_ASSERT(refCount > 0);
4607 }
4608}
4609
4610void InputDispatcher::EventEntry::releaseInjectionState() {
4611 if (injectionState) {
4612 injectionState->release();
Yi Kong9b14ac62018-07-17 13:48:38 -07004613 injectionState = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004614 }
4615}
4616
4617
4618// --- InputDispatcher::ConfigurationChangedEntry ---
4619
Prabir Pradhan42611e02018-11-27 14:04:02 -08004620InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(
4621 uint32_t sequenceNum, nsecs_t eventTime) :
4622 EventEntry(sequenceNum, TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004623}
4624
4625InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
4626}
4627
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004628void InputDispatcher::ConfigurationChangedEntry::appendDescription(std::string& msg) const {
4629 msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004630}
4631
4632
4633// --- InputDispatcher::DeviceResetEntry ---
4634
Prabir Pradhan42611e02018-11-27 14:04:02 -08004635InputDispatcher::DeviceResetEntry::DeviceResetEntry(
4636 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId) :
4637 EventEntry(sequenceNum, TYPE_DEVICE_RESET, eventTime, 0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004638 deviceId(deviceId) {
4639}
4640
4641InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
4642}
4643
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004644void InputDispatcher::DeviceResetEntry::appendDescription(std::string& msg) const {
4645 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x",
Michael Wrightd02c5b62014-02-10 15:10:22 -08004646 deviceId, policyFlags);
4647}
4648
4649
4650// --- InputDispatcher::KeyEntry ---
4651
Prabir Pradhan42611e02018-11-27 14:04:02 -08004652InputDispatcher::KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004653 int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004654 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
4655 int32_t repeatCount, nsecs_t downTime) :
Prabir Pradhan42611e02018-11-27 14:04:02 -08004656 EventEntry(sequenceNum, TYPE_KEY, eventTime, policyFlags),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004657 deviceId(deviceId), source(source), displayId(displayId), action(action), flags(flags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004658 keyCode(keyCode), scanCode(scanCode), metaState(metaState),
4659 repeatCount(repeatCount), downTime(downTime),
4660 syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
4661 interceptKeyWakeupTime(0) {
4662}
4663
4664InputDispatcher::KeyEntry::~KeyEntry() {
4665}
4666
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004667void InputDispatcher::KeyEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004668 msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004669 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
4670 "repeatCount=%d), policyFlags=0x%08x",
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004671 deviceId, source, displayId, keyActionToString(action).c_str(), flags, keyCode,
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004672 scanCode, metaState, repeatCount, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004673}
4674
4675void InputDispatcher::KeyEntry::recycle() {
4676 releaseInjectionState();
4677
4678 dispatchInProgress = false;
4679 syntheticRepeat = false;
4680 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
4681 interceptKeyWakeupTime = 0;
4682}
4683
4684
4685// --- InputDispatcher::MotionEntry ---
4686
Garfield Tan00f511d2019-06-12 16:55:40 -07004687InputDispatcher::MotionEntry::MotionEntry(
4688 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
4689 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004690 int32_t flags, int32_t metaState, int32_t buttonState, MotionClassification classification,
Garfield Tan00f511d2019-06-12 16:55:40 -07004691 int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition,
4692 float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
Jeff Brownf086ddb2014-02-11 14:28:48 -08004693 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
Garfield Tan00f511d2019-06-12 16:55:40 -07004694 float xOffset, float yOffset)
4695 : EventEntry(sequenceNum, TYPE_MOTION, eventTime, policyFlags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004696 eventTime(eventTime),
Garfield Tan00f511d2019-06-12 16:55:40 -07004697 deviceId(deviceId),
4698 source(source),
4699 displayId(displayId),
4700 action(action),
4701 actionButton(actionButton),
4702 flags(flags),
4703 metaState(metaState),
4704 buttonState(buttonState),
4705 classification(classification),
4706 edgeFlags(edgeFlags),
4707 xPrecision(xPrecision),
4708 yPrecision(yPrecision),
4709 xCursorPosition(xCursorPosition),
4710 yCursorPosition(yCursorPosition),
4711 downTime(downTime),
4712 pointerCount(pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004713 for (uint32_t i = 0; i < pointerCount; i++) {
4714 this->pointerProperties[i].copyFrom(pointerProperties[i]);
4715 this->pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004716 if (xOffset || yOffset) {
4717 this->pointerCoords[i].applyOffset(xOffset, yOffset);
4718 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004719 }
4720}
4721
4722InputDispatcher::MotionEntry::~MotionEntry() {
4723}
4724
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004725void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004726 msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07004727 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
4728 "buttonState=0x%08x, "
4729 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
4730 "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
4731 deviceId, source, displayId, motionActionToString(action).c_str(),
4732 actionButton, flags, metaState, buttonState,
4733 motionClassificationToString(classification), edgeFlags, xPrecision,
4734 yPrecision, xCursorPosition, yCursorPosition);
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004735
Michael Wrightd02c5b62014-02-10 15:10:22 -08004736 for (uint32_t i = 0; i < pointerCount; i++) {
4737 if (i) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004738 msg += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004739 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004740 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004741 pointerCoords[i].getX(), pointerCoords[i].getY());
4742 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004743 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004744}
4745
4746
4747// --- InputDispatcher::DispatchEntry ---
4748
4749volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
4750
4751InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
Robert Carre07e1032018-11-26 12:55:53 -08004752 int32_t targetFlags, float xOffset, float yOffset, float globalScaleFactor,
4753 float windowXScale, float windowYScale) :
Michael Wrightd02c5b62014-02-10 15:10:22 -08004754 seq(nextSeq()),
4755 eventEntry(eventEntry), targetFlags(targetFlags),
Robert Carre07e1032018-11-26 12:55:53 -08004756 xOffset(xOffset), yOffset(yOffset), globalScaleFactor(globalScaleFactor),
4757 windowXScale(windowXScale), windowYScale(windowYScale),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004758 deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
4759 eventEntry->refCount += 1;
4760}
4761
4762InputDispatcher::DispatchEntry::~DispatchEntry() {
4763 eventEntry->release();
4764}
4765
4766uint32_t InputDispatcher::DispatchEntry::nextSeq() {
4767 // Sequence number 0 is reserved and will never be returned.
4768 uint32_t seq;
4769 do {
4770 seq = android_atomic_inc(&sNextSeqAtomic);
4771 } while (!seq);
4772 return seq;
4773}
4774
4775
4776// --- InputDispatcher::InputState ---
4777
4778InputDispatcher::InputState::InputState() {
4779}
4780
4781InputDispatcher::InputState::~InputState() {
4782}
4783
4784bool InputDispatcher::InputState::isNeutral() const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004785 return mKeyMementos.empty() && mMotionMementos.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004786}
4787
4788bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
4789 int32_t displayId) const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004790 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004791 if (memento.deviceId == deviceId
4792 && memento.source == source
4793 && memento.displayId == displayId
4794 && memento.hovering) {
4795 return true;
4796 }
4797 }
4798 return false;
4799}
4800
4801bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
4802 int32_t action, int32_t flags) {
4803 switch (action) {
4804 case AKEY_EVENT_ACTION_UP: {
4805 if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
4806 for (size_t i = 0; i < mFallbackKeys.size(); ) {
4807 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
4808 mFallbackKeys.removeItemsAt(i);
4809 } else {
4810 i += 1;
4811 }
4812 }
4813 }
4814 ssize_t index = findKeyMemento(entry);
4815 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004816 mKeyMementos.erase(mKeyMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004817 return true;
4818 }
4819 /* FIXME: We can't just drop the key up event because that prevents creating
4820 * popup windows that are automatically shown when a key is held and then
4821 * dismissed when the key is released. The problem is that the popup will
4822 * not have received the original key down, so the key up will be considered
4823 * to be inconsistent with its observed state. We could perhaps handle this
4824 * by synthesizing a key down but that will cause other problems.
4825 *
4826 * So for now, allow inconsistent key up events to be dispatched.
4827 *
4828#if DEBUG_OUTBOUND_EVENT_DETAILS
4829 ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
4830 "keyCode=%d, scanCode=%d",
4831 entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
4832#endif
4833 return false;
4834 */
4835 return true;
4836 }
4837
4838 case AKEY_EVENT_ACTION_DOWN: {
4839 ssize_t index = findKeyMemento(entry);
4840 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004841 mKeyMementos.erase(mKeyMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004842 }
4843 addKeyMemento(entry, flags);
4844 return true;
4845 }
4846
4847 default:
4848 return true;
4849 }
4850}
4851
4852bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
4853 int32_t action, int32_t flags) {
4854 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
4855 switch (actionMasked) {
4856 case AMOTION_EVENT_ACTION_UP:
4857 case AMOTION_EVENT_ACTION_CANCEL: {
4858 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4859 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004860 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004861 return true;
4862 }
4863#if DEBUG_OUTBOUND_EVENT_DETAILS
4864 ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004865 "displayId=%" PRId32 ", actionMasked=%d",
4866 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004867#endif
4868 return false;
4869 }
4870
4871 case AMOTION_EVENT_ACTION_DOWN: {
4872 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4873 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004874 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004875 }
4876 addMotionMemento(entry, flags, false /*hovering*/);
4877 return true;
4878 }
4879
4880 case AMOTION_EVENT_ACTION_POINTER_UP:
4881 case AMOTION_EVENT_ACTION_POINTER_DOWN:
4882 case AMOTION_EVENT_ACTION_MOVE: {
Michael Wright38dcdff2014-03-19 12:06:10 -07004883 if (entry->source & AINPUT_SOURCE_CLASS_NAVIGATION) {
4884 // Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need to
4885 // generate cancellation events for these since they're based in relative rather than
4886 // absolute units.
4887 return true;
4888 }
4889
Michael Wrightd02c5b62014-02-10 15:10:22 -08004890 ssize_t index = findMotionMemento(entry, false /*hovering*/);
Michael Wright38dcdff2014-03-19 12:06:10 -07004891
4892 if (entry->source & AINPUT_SOURCE_CLASS_JOYSTICK) {
4893 // Joysticks can send MOVE events without a corresponding DOWN or UP. Since all
4894 // joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral. Any
4895 // other value and we need to track the motion so we can send cancellation events for
4896 // anything generating fallback events (e.g. DPad keys for joystick movements).
4897 if (index >= 0) {
4898 if (entry->pointerCoords[0].isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004899 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wright38dcdff2014-03-19 12:06:10 -07004900 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004901 MotionMemento& memento = mMotionMementos[index];
Michael Wright38dcdff2014-03-19 12:06:10 -07004902 memento.setPointers(entry);
4903 }
4904 } else if (!entry->pointerCoords[0].isEmpty()) {
4905 addMotionMemento(entry, flags, false /*hovering*/);
4906 }
4907
4908 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
4909 return true;
4910 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004911 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004912 MotionMemento& memento = mMotionMementos[index];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004913 memento.setPointers(entry);
4914 return true;
4915 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004916#if DEBUG_OUTBOUND_EVENT_DETAILS
4917 ALOGD("Dropping inconsistent motion pointer up/down or move event: "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004918 "deviceId=%d, source=%08x, displayId=%" PRId32 ", actionMasked=%d",
4919 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004920#endif
4921 return false;
4922 }
4923
4924 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
4925 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4926 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004927 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004928 return true;
4929 }
4930#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004931 ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x, "
4932 "displayId=%" PRId32,
4933 entry->deviceId, entry->source, entry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004934#endif
4935 return false;
4936 }
4937
4938 case AMOTION_EVENT_ACTION_HOVER_ENTER:
4939 case AMOTION_EVENT_ACTION_HOVER_MOVE: {
4940 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4941 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004942 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004943 }
4944 addMotionMemento(entry, flags, true /*hovering*/);
4945 return true;
4946 }
4947
4948 default:
4949 return true;
4950 }
4951}
4952
4953ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
4954 for (size_t i = 0; i < mKeyMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004955 const KeyMemento& memento = mKeyMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004956 if (memento.deviceId == entry->deviceId
4957 && memento.source == entry->source
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004958 && memento.displayId == entry->displayId
Michael Wrightd02c5b62014-02-10 15:10:22 -08004959 && memento.keyCode == entry->keyCode
4960 && memento.scanCode == entry->scanCode) {
4961 return i;
4962 }
4963 }
4964 return -1;
4965}
4966
4967ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
4968 bool hovering) const {
4969 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004970 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004971 if (memento.deviceId == entry->deviceId
4972 && memento.source == entry->source
4973 && memento.displayId == entry->displayId
4974 && memento.hovering == hovering) {
4975 return i;
4976 }
4977 }
4978 return -1;
4979}
4980
4981void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004982 KeyMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004983 memento.deviceId = entry->deviceId;
4984 memento.source = entry->source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004985 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004986 memento.keyCode = entry->keyCode;
4987 memento.scanCode = entry->scanCode;
4988 memento.metaState = entry->metaState;
4989 memento.flags = flags;
4990 memento.downTime = entry->downTime;
4991 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004992 mKeyMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004993}
4994
4995void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
4996 int32_t flags, bool hovering) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004997 MotionMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004998 memento.deviceId = entry->deviceId;
4999 memento.source = entry->source;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08005000 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005001 memento.flags = flags;
5002 memento.xPrecision = entry->xPrecision;
5003 memento.yPrecision = entry->yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -07005004 memento.xCursorPosition = entry->xCursorPosition;
5005 memento.yCursorPosition = entry->yCursorPosition;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005006 memento.downTime = entry->downTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005007 memento.setPointers(entry);
5008 memento.hovering = hovering;
5009 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005010 mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005011}
5012
5013void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
5014 pointerCount = entry->pointerCount;
5015 for (uint32_t i = 0; i < entry->pointerCount; i++) {
5016 pointerProperties[i].copyFrom(entry->pointerProperties[i]);
5017 pointerCoords[i].copyFrom(entry->pointerCoords[i]);
5018 }
5019}
5020
5021void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005022 std::vector<EventEntry*>& outEvents, const CancelationOptions& options) {
5023 for (KeyMemento& memento : mKeyMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005024 if (shouldCancelKey(memento, options)) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005025 outEvents.push_back(new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005026 memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08005027 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
5028 memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
5029 }
5030 }
5031
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005032 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005033 if (shouldCancelMotion(memento, options)) {
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08005034 const int32_t action = memento.hovering ?
5035 AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
Garfield Tan00f511d2019-06-12 16:55:40 -07005036 outEvents.push_back(
5037 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, memento.deviceId,
5038 memento.source, memento.displayId, memento.policyFlags, action,
5039 0 /*actionButton*/, memento.flags, AMETA_NONE,
5040 0 /*buttonState*/, MotionClassification::NONE,
5041 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
5042 memento.yPrecision, memento.xCursorPosition,
5043 memento.yCursorPosition, memento.downTime, memento.pointerCount,
5044 memento.pointerProperties, memento.pointerCoords, 0 /*xOffset*/,
5045 0 /*yOffset*/));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005046 }
5047 }
5048}
5049
5050void InputDispatcher::InputState::clear() {
5051 mKeyMementos.clear();
5052 mMotionMementos.clear();
5053 mFallbackKeys.clear();
5054}
5055
5056void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
5057 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005058 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005059 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
5060 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005061 const MotionMemento& otherMemento = other.mMotionMementos[j];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005062 if (memento.deviceId == otherMemento.deviceId
5063 && memento.source == otherMemento.source
5064 && memento.displayId == otherMemento.displayId) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005065 other.mMotionMementos.erase(other.mMotionMementos.begin() + j);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005066 } else {
5067 j += 1;
5068 }
5069 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005070 other.mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005071 }
5072 }
5073}
5074
5075int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
5076 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5077 return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
5078}
5079
5080void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
5081 int32_t fallbackKeyCode) {
5082 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5083 if (index >= 0) {
5084 mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
5085 } else {
5086 mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
5087 }
5088}
5089
5090void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
5091 mFallbackKeys.removeItem(originalKeyCode);
5092}
5093
5094bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
5095 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005096 if (options.keyCode && memento.keyCode != options.keyCode.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005097 return false;
5098 }
5099
Michael Wright3dd60e22019-03-27 22:06:44 +00005100 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5101 return false;
5102 }
5103
5104 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005105 return false;
5106 }
5107
5108 switch (options.mode) {
5109 case CancelationOptions::CANCEL_ALL_EVENTS:
5110 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5111 return true;
5112 case CancelationOptions::CANCEL_FALLBACK_EVENTS:
5113 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
5114 default:
5115 return false;
5116 }
5117}
5118
5119bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
5120 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005121 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5122 return false;
5123 }
5124
5125 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005126 return false;
5127 }
5128
5129 switch (options.mode) {
5130 case CancelationOptions::CANCEL_ALL_EVENTS:
5131 return true;
5132 case CancelationOptions::CANCEL_POINTER_EVENTS:
5133 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
5134 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5135 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
5136 default:
5137 return false;
5138 }
5139}
5140
5141
5142// --- InputDispatcher::Connection ---
5143
Robert Carr803535b2018-08-02 16:38:15 -07005144InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel, bool monitor) :
5145 status(STATUS_NORMAL), inputChannel(inputChannel),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005146 monitor(monitor),
5147 inputPublisher(inputChannel), inputPublisherBlocked(false) {
5148}
5149
5150InputDispatcher::Connection::~Connection() {
5151}
5152
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005153const std::string InputDispatcher::Connection::getWindowName() const {
Robert Carr803535b2018-08-02 16:38:15 -07005154 if (inputChannel != nullptr) {
5155 return inputChannel->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005156 }
5157 if (monitor) {
5158 return "monitor";
5159 }
5160 return "?";
5161}
5162
5163const char* InputDispatcher::Connection::getStatusLabel() const {
5164 switch (status) {
5165 case STATUS_NORMAL:
5166 return "NORMAL";
5167
5168 case STATUS_BROKEN:
5169 return "BROKEN";
5170
5171 case STATUS_ZOMBIE:
5172 return "ZOMBIE";
5173
5174 default:
5175 return "UNKNOWN";
5176 }
5177}
5178
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005179std::deque<InputDispatcher::DispatchEntry*>::iterator
5180InputDispatcher::Connection::findWaitQueueEntry(uint32_t seq) {
5181 for (std::deque<DispatchEntry*>::iterator it = waitQueue.begin(); it != waitQueue.end(); it++) {
5182 if ((*it)->seq == seq) {
5183 return it;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005184 }
5185 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005186 return waitQueue.end();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005187}
5188
Michael Wright3dd60e22019-03-27 22:06:44 +00005189// --- InputDispatcher::Monitor
5190InputDispatcher::Monitor::Monitor(const sp<InputChannel>& inputChannel) :
5191 inputChannel(inputChannel) {
5192}
5193
Michael Wrightd02c5b62014-02-10 15:10:22 -08005194
5195// --- InputDispatcher::CommandEntry ---
Michael Wright3dd60e22019-03-27 22:06:44 +00005196//
Michael Wrightd02c5b62014-02-10 15:10:22 -08005197InputDispatcher::CommandEntry::CommandEntry(Command command) :
Yi Kong9b14ac62018-07-17 13:48:38 -07005198 command(command), eventTime(0), keyEntry(nullptr), userActivityEventType(0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005199 seq(0), handled(false) {
5200}
5201
5202InputDispatcher::CommandEntry::~CommandEntry() {
5203}
5204
Michael Wright3dd60e22019-03-27 22:06:44 +00005205// --- InputDispatcher::TouchedMonitor ---
5206InputDispatcher::TouchedMonitor::TouchedMonitor(const Monitor& monitor, float xOffset,
5207 float yOffset) : monitor(monitor), xOffset(xOffset), yOffset(yOffset) {
5208}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005209
5210// --- InputDispatcher::TouchState ---
5211
5212InputDispatcher::TouchState::TouchState() :
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005213 down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005214}
5215
5216InputDispatcher::TouchState::~TouchState() {
5217}
5218
5219void InputDispatcher::TouchState::reset() {
5220 down = false;
5221 split = false;
5222 deviceId = -1;
5223 source = 0;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005224 displayId = ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005225 windows.clear();
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005226 portalWindows.clear();
Michael Wright3dd60e22019-03-27 22:06:44 +00005227 gestureMonitors.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005228}
5229
5230void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
5231 down = other.down;
5232 split = other.split;
5233 deviceId = other.deviceId;
5234 source = other.source;
5235 displayId = other.displayId;
5236 windows = other.windows;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005237 portalWindows = other.portalWindows;
Michael Wright3dd60e22019-03-27 22:06:44 +00005238 gestureMonitors = other.gestureMonitors;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005239}
5240
5241void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
5242 int32_t targetFlags, BitSet32 pointerIds) {
5243 if (targetFlags & InputTarget::FLAG_SPLIT) {
5244 split = true;
5245 }
5246
5247 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005248 TouchedWindow& touchedWindow = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005249 if (touchedWindow.windowHandle == windowHandle) {
5250 touchedWindow.targetFlags |= targetFlags;
5251 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
5252 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
5253 }
5254 touchedWindow.pointerIds.value |= pointerIds.value;
5255 return;
5256 }
5257 }
5258
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005259 TouchedWindow touchedWindow;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005260 touchedWindow.windowHandle = windowHandle;
5261 touchedWindow.targetFlags = targetFlags;
5262 touchedWindow.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005263 windows.push_back(touchedWindow);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005264}
5265
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005266void InputDispatcher::TouchState::addPortalWindow(const sp<InputWindowHandle>& windowHandle) {
5267 size_t numWindows = portalWindows.size();
5268 for (size_t i = 0; i < numWindows; i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005269 if (portalWindows[i] == windowHandle) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005270 return;
5271 }
5272 }
5273 portalWindows.push_back(windowHandle);
5274}
5275
Michael Wright3dd60e22019-03-27 22:06:44 +00005276void InputDispatcher::TouchState::addGestureMonitors(
5277 const std::vector<TouchedMonitor>& newMonitors) {
5278 const size_t newSize = gestureMonitors.size() + newMonitors.size();
5279 gestureMonitors.reserve(newSize);
5280 gestureMonitors.insert(std::end(gestureMonitors),
5281 std::begin(newMonitors), std::end(newMonitors));
5282}
5283
Michael Wrightd02c5b62014-02-10 15:10:22 -08005284void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
5285 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005286 if (windows[i].windowHandle == windowHandle) {
5287 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005288 return;
5289 }
5290 }
5291}
5292
Robert Carr803535b2018-08-02 16:38:15 -07005293void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) {
5294 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005295 if (windows[i].windowHandle->getToken() == token) {
5296 windows.erase(windows.begin() + i);
Robert Carr803535b2018-08-02 16:38:15 -07005297 return;
5298 }
5299 }
5300}
5301
Michael Wrightd02c5b62014-02-10 15:10:22 -08005302void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
5303 for (size_t i = 0 ; i < windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005304 TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005305 if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
5306 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
5307 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
5308 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
5309 i += 1;
5310 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005311 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005312 }
5313 }
5314}
5315
Michael Wright3dd60e22019-03-27 22:06:44 +00005316void InputDispatcher::TouchState::filterNonMonitors() {
5317 windows.clear();
5318 portalWindows.clear();
5319}
5320
Michael Wrightd02c5b62014-02-10 15:10:22 -08005321sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
5322 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005323 const TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005324 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5325 return window.windowHandle;
5326 }
5327 }
Yi Kong9b14ac62018-07-17 13:48:38 -07005328 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005329}
5330
5331bool InputDispatcher::TouchState::isSlippery() const {
5332 // Must have exactly one foreground window.
5333 bool haveSlipperyForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005334 for (const TouchedWindow& window : windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005335 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5336 if (haveSlipperyForegroundWindow
5337 || !(window.windowHandle->getInfo()->layoutParamsFlags
5338 & InputWindowInfo::FLAG_SLIPPERY)) {
5339 return false;
5340 }
5341 haveSlipperyForegroundWindow = true;
5342 }
5343 }
5344 return haveSlipperyForegroundWindow;
5345}
5346
5347
5348// --- InputDispatcherThread ---
5349
5350InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
5351 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
5352}
5353
5354InputDispatcherThread::~InputDispatcherThread() {
5355}
5356
5357bool InputDispatcherThread::threadLoop() {
5358 mDispatcher->dispatchOnce();
5359 return true;
5360}
5361
5362} // namespace android