blob: 656793a9ca2a79061c1d9c8f2d10c059fe18f2b0 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
Michael Wright3dd60e22019-03-27 22:06:44 +000020#define LOG_NDEBUG 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
31// Log debug messages about registrations.
32#define DEBUG_REGISTRATION 0
33
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
38#define DEBUG_FOCUS 0
39
40// Log debug messages about the app switch latency optimization.
41#define DEBUG_APP_SWITCH 0
42
43// Log debug messages about hover events.
44#define DEBUG_HOVER 0
45
46#include "InputDispatcher.h"
47
Michael Wrightd02c5b62014-02-10 15:10:22 -080048#include <errno.h>
Siarhei Vishniakou443ad902019-03-06 17:25:41 -080049#include <inttypes.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080050#include <limits.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070051#include <stddef.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080052#include <time.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070053#include <unistd.h>
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -070054#include <queue>
55#include <sstream>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070056
Michael Wright2b3c3302018-03-02 17:19:13 +000057#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080058#include <android-base/stringprintf.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070059#include <log/log.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070060#include <utils/Trace.h>
61#include <powermanager/PowerManager.h>
Robert Carr4e670e52018-08-15 13:26:12 -070062#include <binder/Binder.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080063
64#define INDENT " "
65#define INDENT2 " "
66#define INDENT3 " "
67#define INDENT4 " "
68
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080069using android::base::StringPrintf;
70
Michael Wrightd02c5b62014-02-10 15:10:22 -080071namespace android {
72
73// Default input dispatching timeout if there is no focused application or paused window
74// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000075constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080076
77// Amount of time to allow for all pending events to be processed when an app switch
78// key is on the way. This is used to preempt input dispatch and drop input events
79// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000080constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080081
82// Amount of time to allow for an event to be dispatched (measured since its eventTime)
83// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000084constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080085
86// Amount of time to allow touch events to be streamed out to a connection before requiring
87// that the first event be finished. This value extends the ANR timeout by the specified
88// amount. For example, if streaming is allowed to get ahead by one second relative to the
89// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000090constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080091
92// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +000093constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
94
95// Log a warning when an interception call takes longer than this to process.
96constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -080097
98// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +000099constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
100
Prabir Pradhan42611e02018-11-27 14:04:02 -0800101// Sequence number for synthesized or injected events.
102constexpr uint32_t SYNTHESIZED_EVENT_SEQUENCE_NUM = 0;
103
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104
105static inline nsecs_t now() {
106 return systemTime(SYSTEM_TIME_MONOTONIC);
107}
108
109static inline const char* toString(bool value) {
110 return value ? "true" : "false";
111}
112
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800113static std::string motionActionToString(int32_t action) {
114 // Convert MotionEvent action to string
115 switch(action & AMOTION_EVENT_ACTION_MASK) {
116 case AMOTION_EVENT_ACTION_DOWN:
117 return "DOWN";
118 case AMOTION_EVENT_ACTION_MOVE:
119 return "MOVE";
120 case AMOTION_EVENT_ACTION_UP:
121 return "UP";
122 case AMOTION_EVENT_ACTION_POINTER_DOWN:
123 return "POINTER_DOWN";
124 case AMOTION_EVENT_ACTION_POINTER_UP:
125 return "POINTER_UP";
126 }
127 return StringPrintf("%" PRId32, action);
128}
129
130static std::string keyActionToString(int32_t action) {
131 // Convert KeyEvent action to string
Michael Wright3dd60e22019-03-27 22:06:44 +0000132 switch (action) {
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800133 case AKEY_EVENT_ACTION_DOWN:
134 return "DOWN";
135 case AKEY_EVENT_ACTION_UP:
136 return "UP";
137 case AKEY_EVENT_ACTION_MULTIPLE:
138 return "MULTIPLE";
139 }
140 return StringPrintf("%" PRId32, action);
141}
142
Michael Wright3dd60e22019-03-27 22:06:44 +0000143static std::string dispatchModeToString(int32_t dispatchMode) {
144 switch (dispatchMode) {
145 case InputTarget::FLAG_DISPATCH_AS_IS:
146 return "DISPATCH_AS_IS";
147 case InputTarget::FLAG_DISPATCH_AS_OUTSIDE:
148 return "DISPATCH_AS_OUTSIDE";
149 case InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER:
150 return "DISPATCH_AS_HOVER_ENTER";
151 case InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT:
152 return "DISPATCH_AS_HOVER_EXIT";
153 case InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT:
154 return "DISPATCH_AS_SLIPPERY_EXIT";
155 case InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER:
156 return "DISPATCH_AS_SLIPPERY_ENTER";
157 }
158 return StringPrintf("%" PRId32, dispatchMode);
159}
160
Michael Wrightd02c5b62014-02-10 15:10:22 -0800161static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
162 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
163 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
164}
165
166static bool isValidKeyAction(int32_t action) {
167 switch (action) {
168 case AKEY_EVENT_ACTION_DOWN:
169 case AKEY_EVENT_ACTION_UP:
170 return true;
171 default:
172 return false;
173 }
174}
175
176static bool validateKeyEvent(int32_t action) {
177 if (! isValidKeyAction(action)) {
178 ALOGE("Key event has invalid action code 0x%x", action);
179 return false;
180 }
181 return true;
182}
183
Michael Wright7b159c92015-05-14 14:48:03 +0100184static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185 switch (action & AMOTION_EVENT_ACTION_MASK) {
186 case AMOTION_EVENT_ACTION_DOWN:
187 case AMOTION_EVENT_ACTION_UP:
188 case AMOTION_EVENT_ACTION_CANCEL:
189 case AMOTION_EVENT_ACTION_MOVE:
190 case AMOTION_EVENT_ACTION_OUTSIDE:
191 case AMOTION_EVENT_ACTION_HOVER_ENTER:
192 case AMOTION_EVENT_ACTION_HOVER_MOVE:
193 case AMOTION_EVENT_ACTION_HOVER_EXIT:
194 case AMOTION_EVENT_ACTION_SCROLL:
195 return true;
196 case AMOTION_EVENT_ACTION_POINTER_DOWN:
197 case AMOTION_EVENT_ACTION_POINTER_UP: {
198 int32_t index = getMotionEventActionPointerIndex(action);
Dan Albert1bd2fc02016-02-02 15:11:57 -0800199 return index >= 0 && index < pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800200 }
Michael Wright7b159c92015-05-14 14:48:03 +0100201 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
202 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
203 return actionButton != 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 default:
205 return false;
206 }
207}
208
Michael Wright7b159c92015-05-14 14:48:03 +0100209static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800210 const PointerProperties* pointerProperties) {
Michael Wright7b159c92015-05-14 14:48:03 +0100211 if (! isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800212 ALOGE("Motion event has invalid action code 0x%x", action);
213 return false;
214 }
215 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000216 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217 pointerCount, MAX_POINTERS);
218 return false;
219 }
220 BitSet32 pointerIdBits;
221 for (size_t i = 0; i < pointerCount; i++) {
222 int32_t id = pointerProperties[i].id;
223 if (id < 0 || id > MAX_POINTER_ID) {
224 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
225 id, MAX_POINTER_ID);
226 return false;
227 }
228 if (pointerIdBits.hasBit(id)) {
229 ALOGE("Motion event has duplicate pointer id %d", id);
230 return false;
231 }
232 pointerIdBits.markBit(id);
233 }
234 return true;
235}
236
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800237static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800238 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800239 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800240 return;
241 }
242
243 bool first = true;
244 Region::const_iterator cur = region.begin();
245 Region::const_iterator const tail = region.end();
246 while (cur != tail) {
247 if (first) {
248 first = false;
249 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800250 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800251 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800252 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800253 cur++;
254 }
255}
256
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700257/**
258 * Find the entry in std::unordered_map by key, and return it.
259 * If the entry is not found, return a default constructed entry.
260 *
261 * Useful when the entries are vectors, since an empty vector will be returned
262 * if the entry is not found.
263 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
264 */
265template <typename T, typename U>
266static T getValueByKey(const std::unordered_map<U, T>& map, U key) {
267 auto it = map.find(key);
Tiger Huang721e26f2018-07-24 22:26:19 +0800268 return it != map.end() ? it->second : T{};
269}
270
Michael Wrightd02c5b62014-02-10 15:10:22 -0800271
272// --- InputDispatcher ---
273
Garfield Tan00f511d2019-06-12 16:55:40 -0700274InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
275 : mPolicy(policy),
276 mPendingEvent(nullptr),
277 mLastDropReason(DROP_REASON_NOT_DROPPED),
278 mAppSwitchSawKeyDown(false),
279 mAppSwitchDueTime(LONG_LONG_MAX),
280 mNextUnblockedEvent(nullptr),
281 mDispatchEnabled(false),
282 mDispatchFrozen(false),
283 mInputFilterEnabled(false),
284 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
285 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800286 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800287 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800288
Yi Kong9b14ac62018-07-17 13:48:38 -0700289 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800290
291 policy->getDispatcherConfiguration(&mConfig);
292}
293
294InputDispatcher::~InputDispatcher() {
295 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800296 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800297
298 resetKeyRepeatLocked();
299 releasePendingEventLocked();
300 drainInboundQueueLocked();
301 }
302
303 while (mConnectionsByFd.size() != 0) {
304 unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
305 }
306}
307
308void InputDispatcher::dispatchOnce() {
309 nsecs_t nextWakeupTime = LONG_LONG_MAX;
310 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800311 std::scoped_lock _l(mLock);
312 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800313
314 // Run a dispatch loop if there are no pending commands.
315 // The dispatch loop might enqueue commands to run afterwards.
316 if (!haveCommandsLocked()) {
317 dispatchOnceInnerLocked(&nextWakeupTime);
318 }
319
320 // Run all pending commands if there are any.
321 // If any commands were run then force the next poll to wake up immediately.
322 if (runCommandsLockedInterruptible()) {
323 nextWakeupTime = LONG_LONG_MIN;
324 }
325 } // release lock
326
327 // Wait for callback or timeout or wake. (make sure we round up, not down)
328 nsecs_t currentTime = now();
329 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
330 mLooper->pollOnce(timeoutMillis);
331}
332
333void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
334 nsecs_t currentTime = now();
335
Jeff Browndc5992e2014-04-11 01:27:26 -0700336 // Reset the key repeat timer whenever normal dispatch is suspended while the
337 // device is in a non-interactive state. This is to ensure that we abort a key
338 // repeat if the device is just coming out of sleep.
339 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800340 resetKeyRepeatLocked();
341 }
342
343 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
344 if (mDispatchFrozen) {
345#if DEBUG_FOCUS
346 ALOGD("Dispatch frozen. Waiting some more.");
347#endif
348 return;
349 }
350
351 // Optimize latency of app switches.
352 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
353 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
354 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
355 if (mAppSwitchDueTime < *nextWakeupTime) {
356 *nextWakeupTime = mAppSwitchDueTime;
357 }
358
359 // Ready to start a new event.
360 // If we don't already have a pending event, go grab one.
361 if (! mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700362 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800363 if (isAppSwitchDue) {
364 // The inbound queue is empty so the app switch key we were waiting
365 // for will never arrive. Stop waiting for it.
366 resetPendingAppSwitchLocked(false);
367 isAppSwitchDue = false;
368 }
369
370 // Synthesize a key repeat if appropriate.
371 if (mKeyRepeatState.lastKeyEntry) {
372 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
373 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
374 } else {
375 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
376 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
377 }
378 }
379 }
380
381 // Nothing to do if there is no pending event.
382 if (!mPendingEvent) {
383 return;
384 }
385 } else {
386 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700387 mPendingEvent = mInboundQueue.front();
388 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800389 traceInboundQueueLengthLocked();
390 }
391
392 // Poke user activity for this event.
393 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
394 pokeUserActivityLocked(mPendingEvent);
395 }
396
397 // Get ready to dispatch the event.
398 resetANRTimeoutsLocked();
399 }
400
401 // Now we have an event to dispatch.
402 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700403 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800404 bool done = false;
405 DropReason dropReason = DROP_REASON_NOT_DROPPED;
406 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
407 dropReason = DROP_REASON_POLICY;
408 } else if (!mDispatchEnabled) {
409 dropReason = DROP_REASON_DISABLED;
410 }
411
412 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700413 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800414 }
415
416 switch (mPendingEvent->type) {
417 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
418 ConfigurationChangedEntry* typedEntry =
419 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
420 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
421 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
422 break;
423 }
424
425 case EventEntry::TYPE_DEVICE_RESET: {
426 DeviceResetEntry* typedEntry =
427 static_cast<DeviceResetEntry*>(mPendingEvent);
428 done = dispatchDeviceResetLocked(currentTime, typedEntry);
429 dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
430 break;
431 }
432
433 case EventEntry::TYPE_KEY: {
434 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
435 if (isAppSwitchDue) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800436 if (isAppSwitchKeyEvent(typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800437 resetPendingAppSwitchLocked(true);
438 isAppSwitchDue = false;
439 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
440 dropReason = DROP_REASON_APP_SWITCH;
441 }
442 }
443 if (dropReason == DROP_REASON_NOT_DROPPED
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800444 && isStaleEvent(currentTime, typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800445 dropReason = DROP_REASON_STALE;
446 }
447 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
448 dropReason = DROP_REASON_BLOCKED;
449 }
450 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
451 break;
452 }
453
454 case EventEntry::TYPE_MOTION: {
455 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
456 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
457 dropReason = DROP_REASON_APP_SWITCH;
458 }
459 if (dropReason == DROP_REASON_NOT_DROPPED
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800460 && isStaleEvent(currentTime, typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800461 dropReason = DROP_REASON_STALE;
462 }
463 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
464 dropReason = DROP_REASON_BLOCKED;
465 }
466 done = dispatchMotionLocked(currentTime, typedEntry,
467 &dropReason, nextWakeupTime);
468 break;
469 }
470
471 default:
472 ALOG_ASSERT(false);
473 break;
474 }
475
476 if (done) {
477 if (dropReason != DROP_REASON_NOT_DROPPED) {
478 dropInboundEventLocked(mPendingEvent, dropReason);
479 }
Michael Wright3a981722015-06-10 15:26:13 +0100480 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800481
482 releasePendingEventLocked();
483 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
484 }
485}
486
487bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700488 bool needWake = mInboundQueue.empty();
489 mInboundQueue.push_back(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800490 traceInboundQueueLengthLocked();
491
492 switch (entry->type) {
493 case EventEntry::TYPE_KEY: {
494 // Optimize app switch latency.
495 // If the application takes too long to catch up then we drop all events preceding
496 // the app switch key.
497 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800498 if (isAppSwitchKeyEvent(keyEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800499 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
500 mAppSwitchSawKeyDown = true;
501 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
502 if (mAppSwitchSawKeyDown) {
503#if DEBUG_APP_SWITCH
504 ALOGD("App switch is pending!");
505#endif
506 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
507 mAppSwitchSawKeyDown = false;
508 needWake = true;
509 }
510 }
511 }
512 break;
513 }
514
515 case EventEntry::TYPE_MOTION: {
516 // Optimize case where the current application is unresponsive and the user
517 // decides to touch a window in a different application.
518 // If the application takes too long to catch up then we drop all events preceding
519 // the touch into the other window.
520 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
521 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
522 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
523 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
Robert Carr740167f2018-10-11 19:03:41 -0700524 && mInputTargetWaitApplicationToken != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800525 int32_t displayId = motionEntry->displayId;
526 int32_t x = int32_t(motionEntry->pointerCoords[0].
527 getAxisValue(AMOTION_EVENT_AXIS_X));
528 int32_t y = int32_t(motionEntry->pointerCoords[0].
529 getAxisValue(AMOTION_EVENT_AXIS_Y));
530 sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
Yi Kong9b14ac62018-07-17 13:48:38 -0700531 if (touchedWindowHandle != nullptr
Robert Carr740167f2018-10-11 19:03:41 -0700532 && touchedWindowHandle->getApplicationToken()
533 != mInputTargetWaitApplicationToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800534 // User touched a different application than the one we are waiting on.
535 // Flag the event, and start pruning the input queue.
536 mNextUnblockedEvent = motionEntry;
537 needWake = true;
538 }
539 }
540 break;
541 }
542 }
543
544 return needWake;
545}
546
547void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
548 entry->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700549 mRecentQueue.push_back(entry);
550 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
551 mRecentQueue.front()->release();
552 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800553 }
554}
555
556sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800557 int32_t x, int32_t y, bool addOutsideTargets, bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800558 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800559 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
560 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800561 const InputWindowInfo* windowInfo = windowHandle->getInfo();
562 if (windowInfo->displayId == displayId) {
563 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800564
565 if (windowInfo->visible) {
566 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
567 bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
568 | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
569 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800570 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
571 if (portalToDisplayId != ADISPLAY_ID_NONE
572 && portalToDisplayId != displayId) {
573 if (addPortalWindows) {
574 // For the monitoring channels of the display.
575 mTempTouchState.addPortalWindow(windowHandle);
576 }
577 return findTouchedWindowAtLocked(
578 portalToDisplayId, x, y, addOutsideTargets, addPortalWindows);
579 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800580 // Found window.
581 return windowHandle;
582 }
583 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800584
585 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
586 mTempTouchState.addOrUpdateWindow(
587 windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE, BitSet32(0));
588 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800589 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800590 }
591 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700592 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800593}
594
Michael Wright3dd60e22019-03-27 22:06:44 +0000595std::vector<InputDispatcher::TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
596 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
597 std::vector<TouchedMonitor> touchedMonitors;
598
599 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
600 addGestureMonitors(monitors, touchedMonitors);
601 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
602 const InputWindowInfo* windowInfo = portalWindow->getInfo();
603 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
604 addGestureMonitors(monitors, touchedMonitors,
605 -windowInfo->frameLeft, -windowInfo->frameTop);
606 }
607 return touchedMonitors;
608}
609
610void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
611 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset, float yOffset) {
612 if (monitors.empty()) {
613 return;
614 }
615 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
616 for (const Monitor& monitor : monitors) {
617 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
618 }
619}
620
Michael Wrightd02c5b62014-02-10 15:10:22 -0800621void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
622 const char* reason;
623 switch (dropReason) {
624 case DROP_REASON_POLICY:
625#if DEBUG_INBOUND_EVENT_DETAILS
626 ALOGD("Dropped event because policy consumed it.");
627#endif
628 reason = "inbound event was dropped because the policy consumed it";
629 break;
630 case DROP_REASON_DISABLED:
Michael Wright3a981722015-06-10 15:26:13 +0100631 if (mLastDropReason != DROP_REASON_DISABLED) {
632 ALOGI("Dropped event because input dispatch is disabled.");
633 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800634 reason = "inbound event was dropped because input dispatch is disabled";
635 break;
636 case DROP_REASON_APP_SWITCH:
637 ALOGI("Dropped event because of pending overdue app switch.");
638 reason = "inbound event was dropped because of pending overdue app switch";
639 break;
640 case DROP_REASON_BLOCKED:
641 ALOGI("Dropped event because the current application is not responding and the user "
642 "has started interacting with a different application.");
643 reason = "inbound event was dropped because the current application is not responding "
644 "and the user has started interacting with a different application";
645 break;
646 case DROP_REASON_STALE:
647 ALOGI("Dropped event because it is stale.");
648 reason = "inbound event was dropped because it is stale";
649 break;
650 default:
651 ALOG_ASSERT(false);
652 return;
653 }
654
655 switch (entry->type) {
656 case EventEntry::TYPE_KEY: {
657 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
658 synthesizeCancelationEventsForAllConnectionsLocked(options);
659 break;
660 }
661 case EventEntry::TYPE_MOTION: {
662 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
663 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
664 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
665 synthesizeCancelationEventsForAllConnectionsLocked(options);
666 } else {
667 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
668 synthesizeCancelationEventsForAllConnectionsLocked(options);
669 }
670 break;
671 }
672 }
673}
674
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800675static bool isAppSwitchKeyCode(int32_t keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800676 return keyCode == AKEYCODE_HOME
677 || keyCode == AKEYCODE_ENDCALL
678 || keyCode == AKEYCODE_APP_SWITCH;
679}
680
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800681bool InputDispatcher::isAppSwitchKeyEvent(KeyEntry* keyEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800682 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
683 && isAppSwitchKeyCode(keyEntry->keyCode)
684 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
685 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
686}
687
688bool InputDispatcher::isAppSwitchPendingLocked() {
689 return mAppSwitchDueTime != LONG_LONG_MAX;
690}
691
692void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
693 mAppSwitchDueTime = LONG_LONG_MAX;
694
695#if DEBUG_APP_SWITCH
696 if (handled) {
697 ALOGD("App switch has arrived.");
698 } else {
699 ALOGD("App switch was abandoned.");
700 }
701#endif
702}
703
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800704bool InputDispatcher::isStaleEvent(nsecs_t currentTime, EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800705 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
706}
707
708bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700709 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800710}
711
712bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700713 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800714 return false;
715 }
716
717 do {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700718 CommandEntry* commandEntry = mCommandQueue.front();
719 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800720 Command command = commandEntry->command;
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700721 command(*this, commandEntry); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800722
723 commandEntry->connection.clear();
724 delete commandEntry;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700725 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800726 return true;
727}
728
729InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
730 CommandEntry* commandEntry = new CommandEntry(command);
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700731 mCommandQueue.push_back(commandEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800732 return commandEntry;
733}
734
735void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700736 while (!mInboundQueue.empty()) {
737 EventEntry* entry = mInboundQueue.front();
738 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800739 releaseInboundEventLocked(entry);
740 }
741 traceInboundQueueLengthLocked();
742}
743
744void InputDispatcher::releasePendingEventLocked() {
745 if (mPendingEvent) {
746 resetANRTimeoutsLocked();
747 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700748 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800749 }
750}
751
752void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
753 InjectionState* injectionState = entry->injectionState;
754 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
755#if DEBUG_DISPATCH_CYCLE
756 ALOGD("Injected inbound event was dropped.");
757#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800758 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800759 }
760 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700761 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800762 }
763 addRecentEventLocked(entry);
764 entry->release();
765}
766
767void InputDispatcher::resetKeyRepeatLocked() {
768 if (mKeyRepeatState.lastKeyEntry) {
769 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700770 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800771 }
772}
773
774InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
775 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
776
777 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700778 uint32_t policyFlags = entry->policyFlags &
779 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800780 if (entry->refCount == 1) {
781 entry->recycle();
782 entry->eventTime = currentTime;
783 entry->policyFlags = policyFlags;
784 entry->repeatCount += 1;
785 } else {
Prabir Pradhan42611e02018-11-27 14:04:02 -0800786 KeyEntry* newEntry = new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100787 entry->deviceId, entry->source, entry->displayId, policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800788 entry->action, entry->flags, entry->keyCode, entry->scanCode,
789 entry->metaState, entry->repeatCount + 1, entry->downTime);
790
791 mKeyRepeatState.lastKeyEntry = newEntry;
792 entry->release();
793
794 entry = newEntry;
795 }
796 entry->syntheticRepeat = true;
797
798 // Increment reference count since we keep a reference to the event in
799 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
800 entry->refCount += 1;
801
802 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
803 return entry;
804}
805
806bool InputDispatcher::dispatchConfigurationChangedLocked(
807 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
808#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700809 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800810#endif
811
812 // Reset key repeating in case a keyboard device was added or removed or something.
813 resetKeyRepeatLocked();
814
815 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700816 CommandEntry* commandEntry =
817 postCommandLocked(&InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800818 commandEntry->eventTime = entry->eventTime;
819 return true;
820}
821
822bool InputDispatcher::dispatchDeviceResetLocked(
823 nsecs_t currentTime, DeviceResetEntry* entry) {
824#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700825 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
826 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800827#endif
828
829 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
830 "device was reset");
831 options.deviceId = entry->deviceId;
832 synthesizeCancelationEventsForAllConnectionsLocked(options);
833 return true;
834}
835
836bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
837 DropReason* dropReason, nsecs_t* nextWakeupTime) {
838 // Preprocessing.
839 if (! entry->dispatchInProgress) {
840 if (entry->repeatCount == 0
841 && entry->action == AKEY_EVENT_ACTION_DOWN
842 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
843 && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
844 if (mKeyRepeatState.lastKeyEntry
845 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
846 // We have seen two identical key downs in a row which indicates that the device
847 // driver is automatically generating key repeats itself. We take note of the
848 // repeat here, but we disable our own next key repeat timer since it is clear that
849 // we will not need to synthesize key repeats ourselves.
850 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
851 resetKeyRepeatLocked();
852 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
853 } else {
854 // Not a repeat. Save key down state in case we do see a repeat later.
855 resetKeyRepeatLocked();
856 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
857 }
858 mKeyRepeatState.lastKeyEntry = entry;
859 entry->refCount += 1;
860 } else if (! entry->syntheticRepeat) {
861 resetKeyRepeatLocked();
862 }
863
864 if (entry->repeatCount == 1) {
865 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
866 } else {
867 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
868 }
869
870 entry->dispatchInProgress = true;
871
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800872 logOutboundKeyDetails("dispatchKey - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800873 }
874
875 // Handle case where the policy asked us to try again later last time.
876 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
877 if (currentTime < entry->interceptKeyWakeupTime) {
878 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
879 *nextWakeupTime = entry->interceptKeyWakeupTime;
880 }
881 return false; // wait until next wakeup
882 }
883 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
884 entry->interceptKeyWakeupTime = 0;
885 }
886
887 // Give the policy a chance to intercept the key.
888 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
889 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
890 CommandEntry* commandEntry = postCommandLocked(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700891 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +0800892 sp<InputWindowHandle> focusedWindowHandle =
893 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(entry));
894 if (focusedWindowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -0700895 commandEntry->inputChannel =
896 getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800897 }
898 commandEntry->keyEntry = entry;
899 entry->refCount += 1;
900 return false; // wait for the command to run
901 } else {
902 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
903 }
904 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
905 if (*dropReason == DROP_REASON_NOT_DROPPED) {
906 *dropReason = DROP_REASON_POLICY;
907 }
908 }
909
910 // Clean up if dropping the event.
911 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800912 setInjectionResult(entry, *dropReason == DROP_REASON_POLICY
Michael Wrightd02c5b62014-02-10 15:10:22 -0800913 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800914 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800915 return true;
916 }
917
918 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800919 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800920 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
921 entry, inputTargets, nextWakeupTime);
922 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
923 return false;
924 }
925
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800926 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800927 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
928 return true;
929 }
930
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800931 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +0000932 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800933
934 // Dispatch the key.
935 dispatchEventLocked(currentTime, entry, inputTargets);
936 return true;
937}
938
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800939void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800940#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100941 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
942 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +0800943 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800944 prefix,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100945 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800946 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Arthur Hung82a4cad2018-11-15 12:10:30 +0800947 entry->repeatCount, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800948#endif
949}
950
951bool InputDispatcher::dispatchMotionLocked(
952 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000953 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800954 // Preprocessing.
955 if (! entry->dispatchInProgress) {
956 entry->dispatchInProgress = true;
957
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800958 logOutboundMotionDetails("dispatchMotion - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800959 }
960
961 // Clean up if dropping the event.
962 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800963 setInjectionResult(entry, *dropReason == DROP_REASON_POLICY
Michael Wrightd02c5b62014-02-10 15:10:22 -0800964 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
965 return true;
966 }
967
968 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
969
970 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800971 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800972
973 bool conflictingPointerActions = false;
974 int32_t injectionResult;
975 if (isPointerEvent) {
976 // Pointer event. (eg. touchscreen)
977 injectionResult = findTouchedWindowTargetsLocked(currentTime,
978 entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
979 } else {
980 // Non touch event. (eg. trackball)
981 injectionResult = findFocusedWindowTargetsLocked(currentTime,
982 entry, inputTargets, nextWakeupTime);
983 }
984 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
985 return false;
986 }
987
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800988 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800989 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +0100990 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
991 CancelationOptions::Mode mode(isPointerEvent ?
992 CancelationOptions::CANCEL_POINTER_EVENTS :
993 CancelationOptions::CANCEL_NON_POINTER_EVENTS);
994 CancelationOptions options(mode, "input event injection failed");
995 synthesizeCancelationEventsForMonitorsLocked(options);
996 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800997 return true;
998 }
999
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001000 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +00001001 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001002
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001003 if (isPointerEvent) {
1004 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1005 if (stateIndex >= 0) {
1006 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001007 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001008 // The event has gone through these portal windows, so we add monitoring targets of
1009 // the corresponding displays as well.
1010 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001011 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001012 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001013 -windowInfo->frameLeft, -windowInfo->frameTop);
1014 }
1015 }
1016 }
1017 }
1018
Michael Wrightd02c5b62014-02-10 15:10:22 -08001019 // Dispatch the motion.
1020 if (conflictingPointerActions) {
1021 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
1022 "conflicting pointer actions");
1023 synthesizeCancelationEventsForAllConnectionsLocked(options);
1024 }
1025 dispatchEventLocked(currentTime, entry, inputTargets);
1026 return true;
1027}
1028
1029
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001030void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001031#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001032 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1033 ", policyFlags=0x%x, "
Michael Wright7b159c92015-05-14 14:48:03 +01001034 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1035 "metaState=0x%x, buttonState=0x%x,"
Arthur Hung82a4cad2018-11-15 12:10:30 +08001036 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001037 prefix,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001038 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001039 entry->action, entry->actionButton, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001040 entry->metaState, entry->buttonState,
1041 entry->edgeFlags, entry->xPrecision, entry->yPrecision,
Arthur Hung82a4cad2018-11-15 12:10:30 +08001042 entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001043
1044 for (uint32_t i = 0; i < entry->pointerCount; i++) {
1045 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1046 "x=%f, y=%f, pressure=%f, size=%f, "
1047 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001048 "orientation=%f",
Michael Wrightd02c5b62014-02-10 15:10:22 -08001049 i, entry->pointerProperties[i].id,
1050 entry->pointerProperties[i].toolType,
1051 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1052 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1053 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1054 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1055 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1056 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1057 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1058 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001059 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001060 }
1061#endif
1062}
1063
1064void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001065 EventEntry* eventEntry, const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001066 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001067#if DEBUG_DISPATCH_CYCLE
1068 ALOGD("dispatchEventToCurrentInputTargets");
1069#endif
1070
1071 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1072
1073 pokeUserActivityLocked(eventEntry);
1074
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001075 for (const InputTarget& inputTarget : inputTargets) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001076 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
1077 if (connectionIndex >= 0) {
1078 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1079 prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
1080 } else {
1081#if DEBUG_FOCUS
1082 ALOGD("Dropping event delivery to target with channel '%s' because it "
1083 "is no longer registered with the input dispatcher.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001084 inputTarget.inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001085#endif
1086 }
1087 }
1088}
1089
1090int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
1091 const EventEntry* entry,
1092 const sp<InputApplicationHandle>& applicationHandle,
1093 const sp<InputWindowHandle>& windowHandle,
1094 nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001095 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001096 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
1097#if DEBUG_FOCUS
1098 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1099#endif
1100 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1101 mInputTargetWaitStartTime = currentTime;
1102 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1103 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001104 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001105 }
1106 } else {
1107 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1108#if DEBUG_FOCUS
1109 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001110 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001111 reason);
1112#endif
1113 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001114 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001115 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001116 } else if (applicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001117 timeout = applicationHandle->getDispatchingTimeout(
1118 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1119 } else {
1120 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1121 }
1122
1123 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1124 mInputTargetWaitStartTime = currentTime;
1125 mInputTargetWaitTimeoutTime = currentTime + timeout;
1126 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001127 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001128
Yi Kong9b14ac62018-07-17 13:48:38 -07001129 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001130 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001131 }
Robert Carr740167f2018-10-11 19:03:41 -07001132 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1133 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001134 }
1135 }
1136 }
1137
1138 if (mInputTargetWaitTimeoutExpired) {
1139 return INPUT_EVENT_INJECTION_TIMED_OUT;
1140 }
1141
1142 if (currentTime >= mInputTargetWaitTimeoutTime) {
1143 onANRLocked(currentTime, applicationHandle, windowHandle,
1144 entry->eventTime, mInputTargetWaitStartTime, reason);
1145
1146 // Force poll loop to wake up immediately on next iteration once we get the
1147 // ANR response back from the policy.
1148 *nextWakeupTime = LONG_LONG_MIN;
1149 return INPUT_EVENT_INJECTION_PENDING;
1150 } else {
1151 // Force poll loop to wake up when timeout is due.
1152 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1153 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1154 }
1155 return INPUT_EVENT_INJECTION_PENDING;
1156 }
1157}
1158
Robert Carr803535b2018-08-02 16:38:15 -07001159void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1160 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1161 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1162 state.removeWindowByToken(token);
1163 }
1164}
1165
Michael Wrightd02c5b62014-02-10 15:10:22 -08001166void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1167 const sp<InputChannel>& inputChannel) {
1168 if (newTimeout > 0) {
1169 // Extend the timeout.
1170 mInputTargetWaitTimeoutTime = now() + newTimeout;
1171 } else {
1172 // Give up.
1173 mInputTargetWaitTimeoutExpired = true;
1174
1175 // Input state will not be realistic. Mark it out of sync.
1176 if (inputChannel.get()) {
1177 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1178 if (connectionIndex >= 0) {
1179 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
Robert Carr803535b2018-08-02 16:38:15 -07001180 sp<IBinder> token = connection->inputChannel->getToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001181
Robert Carr803535b2018-08-02 16:38:15 -07001182 if (token != nullptr) {
1183 removeWindowByTokenLocked(token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001184 }
1185
1186 if (connection->status == Connection::STATUS_NORMAL) {
1187 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1188 "application not responding");
1189 synthesizeCancelationEventsForConnectionLocked(connection, options);
1190 }
1191 }
1192 }
1193 }
1194}
1195
1196nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
1197 nsecs_t currentTime) {
1198 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1199 return currentTime - mInputTargetWaitStartTime;
1200 }
1201 return 0;
1202}
1203
1204void InputDispatcher::resetANRTimeoutsLocked() {
1205#if DEBUG_FOCUS
1206 ALOGD("Resetting ANR timeouts.");
1207#endif
1208
1209 // Reset input target wait timeout.
1210 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001211 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001212}
1213
Tiger Huang721e26f2018-07-24 22:26:19 +08001214/**
1215 * Get the display id that the given event should go to. If this event specifies a valid display id,
1216 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1217 * Focused display is the display that the user most recently interacted with.
1218 */
1219int32_t InputDispatcher::getTargetDisplayId(const EventEntry* entry) {
1220 int32_t displayId;
1221 switch (entry->type) {
1222 case EventEntry::TYPE_KEY: {
1223 const KeyEntry* typedEntry = static_cast<const KeyEntry*>(entry);
1224 displayId = typedEntry->displayId;
1225 break;
1226 }
1227 case EventEntry::TYPE_MOTION: {
1228 const MotionEntry* typedEntry = static_cast<const MotionEntry*>(entry);
1229 displayId = typedEntry->displayId;
1230 break;
1231 }
1232 default: {
1233 ALOGE("Unsupported event type '%" PRId32 "' for target display.", entry->type);
1234 return ADISPLAY_ID_NONE;
1235 }
1236 }
1237 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1238}
1239
Michael Wrightd02c5b62014-02-10 15:10:22 -08001240int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001241 const EventEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001242 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001243 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001244
Tiger Huang721e26f2018-07-24 22:26:19 +08001245 int32_t displayId = getTargetDisplayId(entry);
1246 sp<InputWindowHandle> focusedWindowHandle =
1247 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1248 sp<InputApplicationHandle> focusedApplicationHandle =
1249 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1250
Michael Wrightd02c5b62014-02-10 15:10:22 -08001251 // If there is no currently focused window and no focused application
1252 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001253 if (focusedWindowHandle == nullptr) {
1254 if (focusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001255 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001256 focusedApplicationHandle, nullptr, nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001257 "Waiting because no window has focus but there is a "
1258 "focused application that may eventually add a window "
1259 "when it finishes starting up.");
1260 goto Unresponsive;
1261 }
1262
Arthur Hung3b413f22018-10-26 18:05:34 +08001263 ALOGI("Dropping event because there is no focused window or focused application in display "
1264 "%" PRId32 ".", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001265 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1266 goto Failed;
1267 }
1268
1269 // Check permissions.
Tiger Huang721e26f2018-07-24 22:26:19 +08001270 if (!checkInjectionPermission(focusedWindowHandle, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001271 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1272 goto Failed;
1273 }
1274
Jeff Brownffb49772014-10-10 19:01:34 -07001275 // Check whether the window is ready for more input.
1276 reason = checkWindowReadyForMoreInputLocked(currentTime,
Tiger Huang721e26f2018-07-24 22:26:19 +08001277 focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001278 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001279 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001280 focusedApplicationHandle, focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001281 goto Unresponsive;
1282 }
1283
1284 // Success! Output targets.
1285 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001286 addWindowTargetLocked(focusedWindowHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001287 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
1288 inputTargets);
1289
1290 // Done.
1291Failed:
1292Unresponsive:
1293 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001294 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001295#if DEBUG_FOCUS
1296 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1297 "timeSpentWaitingForApplication=%0.1fms",
1298 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1299#endif
1300 return injectionResult;
1301}
1302
1303int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001304 const MotionEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001305 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001306 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001307 enum InjectionPermission {
1308 INJECTION_PERMISSION_UNKNOWN,
1309 INJECTION_PERMISSION_GRANTED,
1310 INJECTION_PERMISSION_DENIED
1311 };
1312
Michael Wrightd02c5b62014-02-10 15:10:22 -08001313 // For security reasons, we defer updating the touch state until we are sure that
1314 // event injection will be allowed.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001315 int32_t displayId = entry->displayId;
1316 int32_t action = entry->action;
1317 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1318
1319 // Update the touch state as needed based on the properties of the touch event.
1320 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1321 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1322 sp<InputWindowHandle> newHoverWindowHandle;
1323
Jeff Brownf086ddb2014-02-11 14:28:48 -08001324 // Copy current touch state into mTempTouchState.
1325 // This state is always reset at the end of this function, so if we don't find state
1326 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001327 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001328 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1329 if (oldStateIndex >= 0) {
1330 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1331 mTempTouchState.copyFrom(*oldState);
1332 }
1333
1334 bool isSplit = mTempTouchState.split;
1335 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0
1336 && (mTempTouchState.deviceId != entry->deviceId
1337 || mTempTouchState.source != entry->source
1338 || mTempTouchState.displayId != displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001339 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1340 || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1341 || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1342 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
1343 || maskedAction == AMOTION_EVENT_ACTION_SCROLL
1344 || isHoverAction);
Garfield Tan00f511d2019-06-12 16:55:40 -07001345 const bool isFromMouse = entry->source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001346 bool wrongDevice = false;
1347 if (newGesture) {
1348 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001349 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001350#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001351 ALOGD("Dropping event because a pointer for a different device is already down "
1352 "in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001353#endif
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001354 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001355 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1356 switchedDevice = false;
1357 wrongDevice = true;
1358 goto Failed;
1359 }
1360 mTempTouchState.reset();
1361 mTempTouchState.down = down;
1362 mTempTouchState.deviceId = entry->deviceId;
1363 mTempTouchState.source = entry->source;
1364 mTempTouchState.displayId = displayId;
1365 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001366 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
1367#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001368 ALOGI("Dropping move event because a pointer for a different device is already active "
1369 "in display %" PRId32, displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001370#endif
1371 // TODO: test multiple simultaneous input streams.
1372 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1373 switchedDevice = false;
1374 wrongDevice = true;
1375 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001376 }
1377
1378 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1379 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1380
Garfield Tan00f511d2019-06-12 16:55:40 -07001381 int32_t x;
1382 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001383 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001384 // Always dispatch mouse events to cursor position.
1385 if (isFromMouse) {
1386 x = int32_t(entry->xCursorPosition);
1387 y = int32_t(entry->yCursorPosition);
1388 } else {
1389 x = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1390 y = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
1391 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001392 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001393 sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +00001394 displayId, x, y, isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
1395
1396 std::vector<TouchedMonitor> newGestureMonitors = isDown
1397 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1398 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001399
Michael Wrightd02c5b62014-02-10 15:10:22 -08001400 // Figure out whether splitting will be allowed for this window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001401 if (newTouchedWindowHandle != nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001402 && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001403 // New window supports splitting, but we should never split mouse events.
1404 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001405 } else if (isSplit) {
1406 // New window does not support splitting but we have already split events.
1407 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001408 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001409 }
1410
1411 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001412 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001413 // Try to assign the pointer to the first foreground window we find, if there is one.
1414 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001415 }
1416
1417 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1418 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
1419 "(%d, %d) in display %" PRId32 ".", x, y, displayId);
1420 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1421 goto Failed;
1422 }
1423
1424 if (newTouchedWindowHandle != nullptr) {
1425 // Set target flags.
1426 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1427 if (isSplit) {
1428 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001429 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001430 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1431 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1432 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1433 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1434 }
1435
1436 // Update hover state.
1437 if (isHoverAction) {
1438 newHoverWindowHandle = newTouchedWindowHandle;
1439 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1440 newHoverWindowHandle = mLastHoverWindowHandle;
1441 }
1442
1443 // Update the temporary touch state.
1444 BitSet32 pointerIds;
1445 if (isSplit) {
1446 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1447 pointerIds.markBit(pointerId);
1448 }
1449 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001450 }
1451
Michael Wright3dd60e22019-03-27 22:06:44 +00001452 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001453 } else {
1454 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1455
1456 // If the pointer is not currently down, then ignore the event.
1457 if (! mTempTouchState.down) {
1458#if DEBUG_FOCUS
1459 ALOGD("Dropping event because the pointer is not down or we previously "
Arthur Hung3b413f22018-10-26 18:05:34 +08001460 "dropped the pointer down event in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001461#endif
1462 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1463 goto Failed;
1464 }
1465
1466 // Check whether touches should slip outside of the current foreground window.
1467 if (maskedAction == AMOTION_EVENT_ACTION_MOVE
1468 && entry->pointerCount == 1
1469 && mTempTouchState.isSlippery()) {
1470 int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1471 int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
1472
1473 sp<InputWindowHandle> oldTouchedWindowHandle =
1474 mTempTouchState.getFirstForegroundWindowHandle();
1475 sp<InputWindowHandle> newTouchedWindowHandle =
1476 findTouchedWindowAtLocked(displayId, x, y);
1477 if (oldTouchedWindowHandle != newTouchedWindowHandle
Michael Wright3dd60e22019-03-27 22:06:44 +00001478 && oldTouchedWindowHandle != nullptr
Yi Kong9b14ac62018-07-17 13:48:38 -07001479 && newTouchedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001480#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001481 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001482 oldTouchedWindowHandle->getName().c_str(),
Arthur Hung3b413f22018-10-26 18:05:34 +08001483 newTouchedWindowHandle->getName().c_str(),
1484 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001485#endif
1486 // Make a slippery exit from the old window.
1487 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1488 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
1489
1490 // Make a slippery entrance into the new window.
1491 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1492 isSplit = true;
1493 }
1494
1495 int32_t targetFlags = InputTarget::FLAG_FOREGROUND
1496 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
1497 if (isSplit) {
1498 targetFlags |= InputTarget::FLAG_SPLIT;
1499 }
1500 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1501 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1502 }
1503
1504 BitSet32 pointerIds;
1505 if (isSplit) {
1506 pointerIds.markBit(entry->pointerProperties[0].id);
1507 }
1508 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1509 }
1510 }
1511 }
1512
1513 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1514 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001515 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001516#if DEBUG_HOVER
1517 ALOGD("Sending hover exit event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001518 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001519#endif
1520 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1521 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
1522 }
1523
1524 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001525 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001526#if DEBUG_HOVER
1527 ALOGD("Sending hover enter event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001528 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001529#endif
1530 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1531 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
1532 }
1533 }
1534
1535 // Check permission to inject into all touched foreground windows and ensure there
1536 // is at least one touched foreground window.
1537 {
1538 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001539 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001540 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1541 haveForegroundWindow = true;
1542 if (! checkInjectionPermission(touchedWindow.windowHandle,
1543 entry->injectionState)) {
1544 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1545 injectionPermission = INJECTION_PERMISSION_DENIED;
1546 goto Failed;
1547 }
1548 }
1549 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001550 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1551 if (!haveForegroundWindow && !hasGestureMonitor) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001552#if DEBUG_FOCUS
Michael Wright3dd60e22019-03-27 22:06:44 +00001553 ALOGD("Dropping event because there is no touched foreground window in display %"
1554 PRId32 " or gesture monitor to receive it.", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001555#endif
1556 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1557 goto Failed;
1558 }
1559
1560 // Permission granted to injection into all touched foreground windows.
1561 injectionPermission = INJECTION_PERMISSION_GRANTED;
1562 }
1563
1564 // Check whether windows listening for outside touches are owned by the same UID. If it is
1565 // set the policy flag that we will not reveal coordinate information to this window.
1566 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1567 sp<InputWindowHandle> foregroundWindowHandle =
1568 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001569 if (foregroundWindowHandle) {
1570 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1571 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1572 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1573 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1574 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1575 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
1576 InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
1577 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001578 }
1579 }
1580 }
1581 }
1582
1583 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001584 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001585 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001586 // Check whether the window is ready for more input.
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001587 std::string reason = checkWindowReadyForMoreInputLocked(currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001588 touchedWindow.windowHandle, entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001589 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001590 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Yi Kong9b14ac62018-07-17 13:48:38 -07001591 nullptr, touchedWindow.windowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001592 goto Unresponsive;
1593 }
1594 }
1595 }
1596
1597 // If this is the first pointer going down and the touched window has a wallpaper
1598 // then also add the touched wallpaper windows so they are locked in for the duration
1599 // of the touch gesture.
1600 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1601 // engine only supports touch events. We would need to add a mechanism similar
1602 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1603 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1604 sp<InputWindowHandle> foregroundWindowHandle =
1605 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001606 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001607 const std::vector<sp<InputWindowHandle>> windowHandles =
1608 getWindowHandlesLocked(displayId);
1609 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001610 const InputWindowInfo* info = windowHandle->getInfo();
1611 if (info->displayId == displayId
1612 && windowHandle->getInfo()->layoutParamsType
1613 == InputWindowInfo::TYPE_WALLPAPER) {
1614 mTempTouchState.addOrUpdateWindow(windowHandle,
1615 InputTarget::FLAG_WINDOW_IS_OBSCURED
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001616 | InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED
Michael Wrightd02c5b62014-02-10 15:10:22 -08001617 | InputTarget::FLAG_DISPATCH_AS_IS,
1618 BitSet32(0));
1619 }
1620 }
1621 }
1622 }
1623
1624 // Success! Output targets.
1625 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1626
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001627 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001628 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
1629 touchedWindow.pointerIds, inputTargets);
1630 }
1631
Michael Wright3dd60e22019-03-27 22:06:44 +00001632 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1633 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
1634 touchedMonitor.yOffset, inputTargets);
1635 }
1636
Michael Wrightd02c5b62014-02-10 15:10:22 -08001637 // Drop the outside or hover touch windows since we will not care about them
1638 // in the next iteration.
1639 mTempTouchState.filterNonAsIsTouchWindows();
1640
1641Failed:
1642 // Check injection permission once and for all.
1643 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001644 if (checkInjectionPermission(nullptr, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001645 injectionPermission = INJECTION_PERMISSION_GRANTED;
1646 } else {
1647 injectionPermission = INJECTION_PERMISSION_DENIED;
1648 }
1649 }
1650
1651 // Update final pieces of touch state if the injector had permission.
1652 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1653 if (!wrongDevice) {
1654 if (switchedDevice) {
1655#if DEBUG_FOCUS
1656 ALOGD("Conflicting pointer actions: Switched to a different device.");
1657#endif
1658 *outConflictingPointerActions = true;
1659 }
1660
1661 if (isHoverAction) {
1662 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001663 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001664#if DEBUG_FOCUS
1665 ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
1666#endif
1667 *outConflictingPointerActions = true;
1668 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001669 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001670 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1671 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08001672 mTempTouchState.deviceId = entry->deviceId;
1673 mTempTouchState.source = entry->source;
1674 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001675 }
1676 } else if (maskedAction == AMOTION_EVENT_ACTION_UP
1677 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1678 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001679 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001680 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1681 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001682 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001683#if DEBUG_FOCUS
1684 ALOGD("Conflicting pointer actions: Down received while already down.");
1685#endif
1686 *outConflictingPointerActions = true;
1687 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001688 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1689 // One pointer went up.
1690 if (isSplit) {
1691 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1692 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1693
1694 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001695 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001696 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1697 touchedWindow.pointerIds.clearBit(pointerId);
1698 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001699 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001700 continue;
1701 }
1702 }
1703 i += 1;
1704 }
1705 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001706 }
1707
1708 // Save changes unless the action was scroll in which case the temporary touch
1709 // state was only valid for this one action.
1710 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1711 if (mTempTouchState.displayId >= 0) {
1712 if (oldStateIndex >= 0) {
1713 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1714 } else {
1715 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1716 }
1717 } else if (oldStateIndex >= 0) {
1718 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1719 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001720 }
1721
1722 // Update hover state.
1723 mLastHoverWindowHandle = newHoverWindowHandle;
1724 }
1725 } else {
1726#if DEBUG_FOCUS
1727 ALOGD("Not updating touch focus because injection was denied.");
1728#endif
1729 }
1730
1731Unresponsive:
1732 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1733 mTempTouchState.reset();
1734
1735 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001736 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001737#if DEBUG_FOCUS
1738 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1739 "timeSpentWaitingForApplication=%0.1fms",
1740 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1741#endif
1742 return injectionResult;
1743}
1744
1745void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001746 int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets) {
Arthur Hungceeb5d72018-12-05 16:14:18 +08001747 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1748 if (inputChannel == nullptr) {
1749 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1750 return;
1751 }
1752
Michael Wrightd02c5b62014-02-10 15:10:22 -08001753 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001754 InputTarget target;
Arthur Hungceeb5d72018-12-05 16:14:18 +08001755 target.inputChannel = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001756 target.flags = targetFlags;
1757 target.xOffset = - windowInfo->frameLeft;
1758 target.yOffset = - windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08001759 target.globalScaleFactor = windowInfo->globalScaleFactor;
1760 target.windowXScale = windowInfo->windowXScale;
1761 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001762 target.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001763 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001764}
1765
Michael Wright3dd60e22019-03-27 22:06:44 +00001766void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
1767 int32_t displayId, float xOffset, float yOffset) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001768
Michael Wright3dd60e22019-03-27 22:06:44 +00001769 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1770 mGlobalMonitorsByDisplay.find(displayId);
1771
1772 if (it != mGlobalMonitorsByDisplay.end()) {
1773 const std::vector<Monitor>& monitors = it->second;
1774 for (const Monitor& monitor : monitors) {
1775 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001776 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001777 }
1778}
1779
Michael Wright3dd60e22019-03-27 22:06:44 +00001780void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor,
1781 float xOffset, float yOffset, std::vector<InputTarget>& inputTargets) {
1782 InputTarget target;
1783 target.inputChannel = monitor.inputChannel;
1784 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1785 target.xOffset = xOffset;
1786 target.yOffset = yOffset;
1787 target.pointerIds.clear();
1788 target.globalScaleFactor = 1.0f;
1789 inputTargets.push_back(target);
1790}
1791
Michael Wrightd02c5b62014-02-10 15:10:22 -08001792bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
1793 const InjectionState* injectionState) {
1794 if (injectionState
Yi Kong9b14ac62018-07-17 13:48:38 -07001795 && (windowHandle == nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001796 || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
1797 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001798 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001799 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
1800 "owned by uid %d",
1801 injectionState->injectorPid, injectionState->injectorUid,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001802 windowHandle->getName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001803 windowHandle->getInfo()->ownerUid);
1804 } else {
1805 ALOGW("Permission denied: injecting event from pid %d uid %d",
1806 injectionState->injectorPid, injectionState->injectorUid);
1807 }
1808 return false;
1809 }
1810 return true;
1811}
1812
1813bool InputDispatcher::isWindowObscuredAtPointLocked(
1814 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
1815 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001816 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1817 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001818 if (otherHandle == windowHandle) {
1819 break;
1820 }
1821
1822 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1823 if (otherInfo->displayId == displayId
1824 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1825 && otherInfo->frameContainsPoint(x, y)) {
1826 return true;
1827 }
1828 }
1829 return false;
1830}
1831
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001832
1833bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1834 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001835 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001836 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001837 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001838 if (otherHandle == windowHandle) {
1839 break;
1840 }
1841
1842 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1843 if (otherInfo->displayId == displayId
1844 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1845 && otherInfo->overlaps(windowInfo)) {
1846 return true;
1847 }
1848 }
1849 return false;
1850}
1851
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001852std::string InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001853 const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry,
1854 const char* targetType) {
1855 // If the window is paused then keep waiting.
1856 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001857 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001858 }
1859
1860 // If the window's connection is not registered then keep waiting.
Robert Carr5c8a0262018-10-03 16:30:44 -07001861 ssize_t connectionIndex = getConnectionIndexLocked(
1862 getInputChannelLocked(windowHandle->getToken()));
Jeff Brownffb49772014-10-10 19:01:34 -07001863 if (connectionIndex < 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001864 return StringPrintf("Waiting because the %s window's input channel is not "
Jeff Brownffb49772014-10-10 19:01:34 -07001865 "registered with the input dispatcher. The window may be in the process "
1866 "of being removed.", targetType);
1867 }
1868
1869 // If the connection is dead then keep waiting.
1870 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1871 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001872 return StringPrintf("Waiting because the %s window's input connection is %s."
Jeff Brownffb49772014-10-10 19:01:34 -07001873 "The window may be in the process of being removed.", targetType,
1874 connection->getStatusLabel());
1875 }
1876
1877 // If the connection is backed up then keep waiting.
1878 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001879 return StringPrintf("Waiting because the %s window's input channel is full. "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001880 "Outbound queue length: %zu. Wait queue length: %zu.",
1881 targetType, connection->outboundQueue.size(),
1882 connection->waitQueue.size());
Jeff Brownffb49772014-10-10 19:01:34 -07001883 }
1884
1885 // Ensure that the dispatch queues aren't too far backed up for this event.
1886 if (eventEntry->type == EventEntry::TYPE_KEY) {
1887 // If the event is a key event, then we must wait for all previous events to
1888 // complete before delivering it because previous events may have the
1889 // side-effect of transferring focus to a different window and we want to
1890 // ensure that the following keys are sent to the new window.
1891 //
1892 // Suppose the user touches a button in a window then immediately presses "A".
1893 // If the button causes a pop-up window to appear then we want to ensure that
1894 // the "A" key is delivered to the new pop-up window. This is because users
1895 // often anticipate pending UI changes when typing on a keyboard.
1896 // To obtain this behavior, we must serialize key events with respect to all
1897 // prior input events.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001898 if (!connection->outboundQueue.empty() || !connection->waitQueue.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001899 return StringPrintf("Waiting to send key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001900 "finished processing all of the input events that were previously "
1901 "delivered to it. Outbound queue length: %zu. Wait queue length: "
1902 "%zu.",
1903 targetType, connection->outboundQueue.size(),
1904 connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001905 }
Jeff Brownffb49772014-10-10 19:01:34 -07001906 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001907 // Touch events can always be sent to a window immediately because the user intended
1908 // to touch whatever was visible at the time. Even if focus changes or a new
1909 // window appears moments later, the touch event was meant to be delivered to
1910 // whatever window happened to be on screen at the time.
1911 //
1912 // Generic motion events, such as trackball or joystick events are a little trickier.
1913 // Like key events, generic motion events are delivered to the focused window.
1914 // Unlike key events, generic motion events don't tend to transfer focus to other
1915 // windows and it is not important for them to be serialized. So we prefer to deliver
1916 // generic motion events as soon as possible to improve efficiency and reduce lag
1917 // through batching.
1918 //
1919 // The one case where we pause input event delivery is when the wait queue is piling
1920 // up with lots of events because the application is not responding.
1921 // This condition ensures that ANRs are detected reliably.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001922 if (!connection->waitQueue.empty() &&
1923 currentTime >=
1924 connection->waitQueue.front()->deliveryTime + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001925 return StringPrintf("Waiting to send non-key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001926 "finished processing certain input events that were delivered to "
1927 "it over "
1928 "%0.1fms ago. Wait queue length: %zu. Wait queue head age: "
1929 "%0.1fms.",
1930 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
1931 connection->waitQueue.size(),
1932 (currentTime - connection->waitQueue.front()->deliveryTime) *
1933 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001934 }
1935 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001936 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001937}
1938
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001939std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08001940 const sp<InputApplicationHandle>& applicationHandle,
1941 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001942 if (applicationHandle != nullptr) {
1943 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001944 std::string label(applicationHandle->getName());
1945 label += " - ";
1946 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001947 return label;
1948 } else {
1949 return applicationHandle->getName();
1950 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001951 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001952 return windowHandle->getName();
1953 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001954 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001955 }
1956}
1957
1958void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001959 int32_t displayId = getTargetDisplayId(eventEntry);
1960 sp<InputWindowHandle> focusedWindowHandle =
1961 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1962 if (focusedWindowHandle != nullptr) {
1963 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001964 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
1965#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001966 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001967#endif
1968 return;
1969 }
1970 }
1971
1972 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
1973 switch (eventEntry->type) {
1974 case EventEntry::TYPE_MOTION: {
1975 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1976 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1977 return;
1978 }
1979
1980 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
1981 eventType = USER_ACTIVITY_EVENT_TOUCH;
1982 }
1983 break;
1984 }
1985 case EventEntry::TYPE_KEY: {
1986 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1987 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1988 return;
1989 }
1990 eventType = USER_ACTIVITY_EVENT_BUTTON;
1991 break;
1992 }
1993 }
1994
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001995 CommandEntry* commandEntry =
1996 postCommandLocked(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001997 commandEntry->eventTime = eventEntry->eventTime;
1998 commandEntry->userActivityEventType = eventType;
1999}
2000
2001void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
2002 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002003 if (ATRACE_ENABLED()) {
2004 std::string message = StringPrintf(
2005 "prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2006 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
2007 ATRACE_NAME(message.c_str());
2008 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002009#if DEBUG_DISPATCH_CYCLE
2010 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Robert Carre07e1032018-11-26 12:55:53 -08002011 "xOffset=%f, yOffset=%f, globalScaleFactor=%f, "
2012 "windowScaleFactor=(%f, %f), pointerIds=0x%x",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002013 connection->getInputChannelName().c_str(), inputTarget->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002014 inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08002015 inputTarget->globalScaleFactor,
2016 inputTarget->windowXScale, inputTarget->windowYScale,
2017 inputTarget->pointerIds.value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002018#endif
2019
2020 // Skip this event if the connection status is not normal.
2021 // We don't want to enqueue additional outbound events if the connection is broken.
2022 if (connection->status != Connection::STATUS_NORMAL) {
2023#if DEBUG_DISPATCH_CYCLE
2024 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002025 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002026#endif
2027 return;
2028 }
2029
2030 // Split a motion event if needed.
2031 if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
2032 ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
2033
2034 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
2035 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
2036 MotionEntry* splitMotionEntry = splitMotionEvent(
2037 originalMotionEntry, inputTarget->pointerIds);
2038 if (!splitMotionEntry) {
2039 return; // split event was dropped
2040 }
2041#if DEBUG_FOCUS
2042 ALOGD("channel '%s' ~ Split motion event.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002043 connection->getInputChannelName().c_str());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002044 logOutboundMotionDetails(" ", splitMotionEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002045#endif
2046 enqueueDispatchEntriesLocked(currentTime, connection,
2047 splitMotionEntry, inputTarget);
2048 splitMotionEntry->release();
2049 return;
2050 }
2051 }
2052
2053 // Not splitting. Enqueue dispatch entries for the event as is.
2054 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2055}
2056
2057void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
2058 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002059 if (ATRACE_ENABLED()) {
2060 std::string message = StringPrintf(
2061 "enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2062 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
2063 ATRACE_NAME(message.c_str());
2064 }
2065
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002066 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067
2068 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002069 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002070 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002071 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002072 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002073 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002074 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002075 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002076 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002077 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002078 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002079 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002080 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
2081
2082 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002083 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002084 startDispatchCycleLocked(currentTime, connection);
2085 }
2086}
2087
chaviw8c9cf542019-03-25 13:02:48 -07002088void InputDispatcher::enqueueDispatchEntryLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002089 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
2090 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002091 if (ATRACE_ENABLED()) {
2092 std::string message = StringPrintf(
2093 "enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2094 connection->getInputChannelName().c_str(),
2095 dispatchModeToString(dispatchMode).c_str());
2096 ATRACE_NAME(message.c_str());
2097 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002098 int32_t inputTargetFlags = inputTarget->flags;
2099 if (!(inputTargetFlags & dispatchMode)) {
2100 return;
2101 }
2102 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2103
2104 // This is a new event.
2105 // Enqueue a new dispatch entry onto the outbound queue for this connection.
2106 DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
2107 inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08002108 inputTarget->globalScaleFactor, inputTarget->windowXScale,
2109 inputTarget->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002110
2111 // Apply target flags and update the connection's input state.
2112 switch (eventEntry->type) {
2113 case EventEntry::TYPE_KEY: {
2114 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2115 dispatchEntry->resolvedAction = keyEntry->action;
2116 dispatchEntry->resolvedFlags = keyEntry->flags;
2117
2118 if (!connection->inputState.trackKey(keyEntry,
2119 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2120#if DEBUG_DISPATCH_CYCLE
2121 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002122 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002123#endif
2124 delete dispatchEntry;
2125 return; // skip the inconsistent event
2126 }
2127 break;
2128 }
2129
2130 case EventEntry::TYPE_MOTION: {
2131 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2132 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2133 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2134 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2135 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2136 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2137 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2138 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2139 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2140 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2141 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2142 } else {
2143 dispatchEntry->resolvedAction = motionEntry->action;
2144 }
2145 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
2146 && !connection->inputState.isHovering(
2147 motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
2148#if DEBUG_DISPATCH_CYCLE
2149 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002150 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002151#endif
2152 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2153 }
2154
2155 dispatchEntry->resolvedFlags = motionEntry->flags;
2156 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2157 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2158 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002159 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2160 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2161 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002162
2163 if (!connection->inputState.trackMotion(motionEntry,
2164 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2165#if DEBUG_DISPATCH_CYCLE
2166 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002167 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002168#endif
2169 delete dispatchEntry;
2170 return; // skip the inconsistent event
2171 }
chaviw8c9cf542019-03-25 13:02:48 -07002172
chaviwfd6d3512019-03-25 13:23:49 -07002173 dispatchPointerDownOutsideFocus(motionEntry->source,
chaviw8c9cf542019-03-25 13:02:48 -07002174 dispatchEntry->resolvedAction, inputTarget->inputChannel->getToken());
2175
Michael Wrightd02c5b62014-02-10 15:10:22 -08002176 break;
2177 }
2178 }
2179
2180 // Remember that we are waiting for this dispatch to complete.
2181 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002182 incrementPendingForegroundDispatches(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002183 }
2184
2185 // Enqueue the dispatch entry.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002186 connection->outboundQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002187 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002188
2189}
2190
chaviwfd6d3512019-03-25 13:23:49 -07002191void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
chaviw8c9cf542019-03-25 13:02:48 -07002192 const sp<IBinder>& newToken) {
2193 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002194 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2195 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002196 return;
2197 }
2198
2199 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2200 if (inputWindowHandle == nullptr) {
2201 return;
2202 }
2203
chaviw8c9cf542019-03-25 13:02:48 -07002204 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002205 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002206
2207 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2208
2209 if (!hasFocusChanged) {
2210 return;
2211 }
2212
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07002213 CommandEntry* commandEntry =
2214 postCommandLocked(&InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002215 commandEntry->newToken = newToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002216}
2217
2218void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
2219 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002220 if (ATRACE_ENABLED()) {
2221 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
2222 connection->getInputChannelName().c_str());
2223 ATRACE_NAME(message.c_str());
2224 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002225#if DEBUG_DISPATCH_CYCLE
2226 ALOGD("channel '%s' ~ startDispatchCycle",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002227 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002228#endif
2229
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002230 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2231 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002232 dispatchEntry->deliveryTime = currentTime;
2233
2234 // Publish the event.
2235 status_t status;
2236 EventEntry* eventEntry = dispatchEntry->eventEntry;
2237 switch (eventEntry->type) {
2238 case EventEntry::TYPE_KEY: {
2239 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2240
2241 // Publish the key event.
2242 status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002243 keyEntry->deviceId, keyEntry->source, keyEntry->displayId,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002244 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
2245 keyEntry->keyCode, keyEntry->scanCode,
2246 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
2247 keyEntry->eventTime);
2248 break;
2249 }
2250
2251 case EventEntry::TYPE_MOTION: {
2252 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2253
2254 PointerCoords scaledCoords[MAX_POINTERS];
2255 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2256
2257 // Set the X and Y offset depending on the input source.
Siarhei Vishniakou635cb712017-11-01 16:32:14 -07002258 float xOffset, yOffset;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002259 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
2260 && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
Robert Carre07e1032018-11-26 12:55:53 -08002261 float globalScaleFactor = dispatchEntry->globalScaleFactor;
2262 float wxs = dispatchEntry->windowXScale;
2263 float wys = dispatchEntry->windowYScale;
2264 xOffset = dispatchEntry->xOffset * wxs;
2265 yOffset = dispatchEntry->yOffset * wys;
2266 if (wxs != 1.0f || wys != 1.0f || globalScaleFactor != 1.0f) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002267 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002268 scaledCoords[i] = motionEntry->pointerCoords[i];
Robert Carre07e1032018-11-26 12:55:53 -08002269 scaledCoords[i].scale(globalScaleFactor, wxs, wys);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002270 }
2271 usingCoords = scaledCoords;
2272 }
2273 } else {
2274 xOffset = 0.0f;
2275 yOffset = 0.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002276
2277 // We don't want the dispatch target to know.
2278 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002279 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002280 scaledCoords[i].clear();
2281 }
2282 usingCoords = scaledCoords;
2283 }
2284 }
2285
2286 // Publish the motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002287 status =
2288 connection->inputPublisher
2289 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2290 motionEntry->source, motionEntry->displayId,
2291 dispatchEntry->resolvedAction,
2292 motionEntry->actionButton,
2293 dispatchEntry->resolvedFlags,
2294 motionEntry->edgeFlags, motionEntry->metaState,
2295 motionEntry->buttonState,
2296 motionEntry->classification, xOffset, yOffset,
2297 motionEntry->xPrecision, motionEntry->yPrecision,
2298 motionEntry->xCursorPosition,
2299 motionEntry->yCursorPosition, motionEntry->downTime,
2300 motionEntry->eventTime, motionEntry->pointerCount,
2301 motionEntry->pointerProperties, usingCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002302 break;
2303 }
2304
2305 default:
2306 ALOG_ASSERT(false);
2307 return;
2308 }
2309
2310 // Check the result.
2311 if (status) {
2312 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002313 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002314 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
2315 "This is unexpected because the wait queue is empty, so the pipe "
2316 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002317 "event to it, status=%d", connection->getInputChannelName().c_str(),
2318 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002319 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2320 } else {
2321 // Pipe is full and we are waiting for the app to finish process some events
2322 // before sending more events to it.
2323#if DEBUG_DISPATCH_CYCLE
2324 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
2325 "waiting for the application to catch up",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002326 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002327#endif
2328 connection->inputPublisherBlocked = true;
2329 }
2330 } else {
2331 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002332 "status=%d", connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002333 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2334 }
2335 return;
2336 }
2337
2338 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002339 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2340 connection->outboundQueue.end(),
2341 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002342 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002343 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002344 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002345 }
2346}
2347
2348void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
2349 const sp<Connection>& connection, uint32_t seq, bool handled) {
2350#if DEBUG_DISPATCH_CYCLE
2351 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002352 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002353#endif
2354
2355 connection->inputPublisherBlocked = false;
2356
2357 if (connection->status == Connection::STATUS_BROKEN
2358 || connection->status == Connection::STATUS_ZOMBIE) {
2359 return;
2360 }
2361
2362 // Notify other system components and prepare to start the next dispatch cycle.
2363 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2364}
2365
2366void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
2367 const sp<Connection>& connection, bool notify) {
2368#if DEBUG_DISPATCH_CYCLE
2369 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002370 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002371#endif
2372
2373 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002374 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002375 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002376 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002377 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002378
2379 // The connection appears to be unrecoverably broken.
2380 // Ignore already broken or zombie connections.
2381 if (connection->status == Connection::STATUS_NORMAL) {
2382 connection->status = Connection::STATUS_BROKEN;
2383
2384 if (notify) {
2385 // Notify other system components.
2386 onDispatchCycleBrokenLocked(currentTime, connection);
2387 }
2388 }
2389}
2390
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002391void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2392 while (!queue.empty()) {
2393 DispatchEntry* dispatchEntry = queue.front();
2394 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002395 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002396 }
2397}
2398
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002399void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002400 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002401 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002402 }
2403 delete dispatchEntry;
2404}
2405
2406int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2407 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2408
2409 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002410 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002411
2412 ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
2413 if (connectionIndex < 0) {
2414 ALOGE("Received spurious receive callback for unknown input channel. "
2415 "fd=%d, events=0x%x", fd, events);
2416 return 0; // remove the callback
2417 }
2418
2419 bool notify;
2420 sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
2421 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2422 if (!(events & ALOOPER_EVENT_INPUT)) {
2423 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002424 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002425 return 1;
2426 }
2427
2428 nsecs_t currentTime = now();
2429 bool gotOne = false;
2430 status_t status;
2431 for (;;) {
2432 uint32_t seq;
2433 bool handled;
2434 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2435 if (status) {
2436 break;
2437 }
2438 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2439 gotOne = true;
2440 }
2441 if (gotOne) {
2442 d->runCommandsLockedInterruptible();
2443 if (status == WOULD_BLOCK) {
2444 return 1;
2445 }
2446 }
2447
2448 notify = status != DEAD_OBJECT || !connection->monitor;
2449 if (notify) {
2450 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002451 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002452 }
2453 } else {
2454 // Monitor channels are never explicitly unregistered.
2455 // We do it automatically when the remote endpoint is closed so don't warn
2456 // about them.
2457 notify = !connection->monitor;
2458 if (notify) {
2459 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002460 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002461 }
2462 }
2463
2464 // Unregister the channel.
2465 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2466 return 0; // remove the callback
2467 } // release lock
2468}
2469
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002470void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked (
Michael Wrightd02c5b62014-02-10 15:10:22 -08002471 const CancelationOptions& options) {
2472 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
2473 synthesizeCancelationEventsForConnectionLocked(
2474 mConnectionsByFd.valueAt(i), options);
2475 }
2476}
2477
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002478void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked (
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002479 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002480 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2481 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2482}
2483
2484void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2485 const CancelationOptions& options,
2486 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2487 for (const auto& it : monitorsByDisplay) {
2488 const std::vector<Monitor>& monitors = it.second;
2489 for (const Monitor& monitor : monitors) {
2490 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002491 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002492 }
2493}
2494
Michael Wrightd02c5b62014-02-10 15:10:22 -08002495void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2496 const sp<InputChannel>& channel, const CancelationOptions& options) {
2497 ssize_t index = getConnectionIndexLocked(channel);
2498 if (index >= 0) {
2499 synthesizeCancelationEventsForConnectionLocked(
2500 mConnectionsByFd.valueAt(index), options);
2501 }
2502}
2503
2504void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2505 const sp<Connection>& connection, const CancelationOptions& options) {
2506 if (connection->status == Connection::STATUS_BROKEN) {
2507 return;
2508 }
2509
2510 nsecs_t currentTime = now();
2511
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002512 std::vector<EventEntry*> cancelationEvents;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002513 connection->inputState.synthesizeCancelationEvents(currentTime,
2514 cancelationEvents, options);
2515
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002516 if (!cancelationEvents.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002517#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002518 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Michael Wrightd02c5b62014-02-10 15:10:22 -08002519 "with reality: %s, mode=%d.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002520 connection->getInputChannelName().c_str(), cancelationEvents.size(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002521 options.reason, options.mode);
2522#endif
2523 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002524 EventEntry* cancelationEventEntry = cancelationEvents[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002525 switch (cancelationEventEntry->type) {
2526 case EventEntry::TYPE_KEY:
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002527 logOutboundKeyDetails("cancel - ",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002528 static_cast<KeyEntry*>(cancelationEventEntry));
2529 break;
2530 case EventEntry::TYPE_MOTION:
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002531 logOutboundMotionDetails("cancel - ",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002532 static_cast<MotionEntry*>(cancelationEventEntry));
2533 break;
2534 }
2535
2536 InputTarget target;
chaviwfbe5d9c2018-12-26 12:23:37 -08002537 sp<InputWindowHandle> windowHandle = getWindowHandleLocked(
2538 connection->inputChannel->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07002539 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002540 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2541 target.xOffset = -windowInfo->frameLeft;
2542 target.yOffset = -windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08002543 target.globalScaleFactor = windowInfo->globalScaleFactor;
2544 target.windowXScale = windowInfo->windowXScale;
2545 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002546 } else {
2547 target.xOffset = 0;
2548 target.yOffset = 0;
Robert Carre07e1032018-11-26 12:55:53 -08002549 target.globalScaleFactor = 1.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002550 }
2551 target.inputChannel = connection->inputChannel;
2552 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2553
chaviw8c9cf542019-03-25 13:02:48 -07002554 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
Michael Wrightd02c5b62014-02-10 15:10:22 -08002555 &target, InputTarget::FLAG_DISPATCH_AS_IS);
2556
2557 cancelationEventEntry->release();
2558 }
2559
2560 startDispatchCycleLocked(currentTime, connection);
2561 }
2562}
2563
2564InputDispatcher::MotionEntry*
2565InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2566 ALOG_ASSERT(pointerIds.value != 0);
2567
2568 uint32_t splitPointerIndexMap[MAX_POINTERS];
2569 PointerProperties splitPointerProperties[MAX_POINTERS];
2570 PointerCoords splitPointerCoords[MAX_POINTERS];
2571
2572 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2573 uint32_t splitPointerCount = 0;
2574
2575 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2576 originalPointerIndex++) {
2577 const PointerProperties& pointerProperties =
2578 originalMotionEntry->pointerProperties[originalPointerIndex];
2579 uint32_t pointerId = uint32_t(pointerProperties.id);
2580 if (pointerIds.hasBit(pointerId)) {
2581 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2582 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2583 splitPointerCoords[splitPointerCount].copyFrom(
2584 originalMotionEntry->pointerCoords[originalPointerIndex]);
2585 splitPointerCount += 1;
2586 }
2587 }
2588
2589 if (splitPointerCount != pointerIds.count()) {
2590 // This is bad. We are missing some of the pointers that we expected to deliver.
2591 // Most likely this indicates that we received an ACTION_MOVE events that has
2592 // different pointer ids than we expected based on the previous ACTION_DOWN
2593 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2594 // in this way.
2595 ALOGW("Dropping split motion event because the pointer count is %d but "
2596 "we expected there to be %d pointers. This probably means we received "
2597 "a broken sequence of pointer ids from the input device.",
2598 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002599 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002600 }
2601
2602 int32_t action = originalMotionEntry->action;
2603 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2604 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2605 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2606 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2607 const PointerProperties& pointerProperties =
2608 originalMotionEntry->pointerProperties[originalPointerIndex];
2609 uint32_t pointerId = uint32_t(pointerProperties.id);
2610 if (pointerIds.hasBit(pointerId)) {
2611 if (pointerIds.count() == 1) {
2612 // The first/last pointer went down/up.
2613 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2614 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2615 } else {
2616 // A secondary pointer went down/up.
2617 uint32_t splitPointerIndex = 0;
2618 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2619 splitPointerIndex += 1;
2620 }
2621 action = maskedAction | (splitPointerIndex
2622 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2623 }
2624 } else {
2625 // An unrelated pointer changed.
2626 action = AMOTION_EVENT_ACTION_MOVE;
2627 }
2628 }
2629
Garfield Tan00f511d2019-06-12 16:55:40 -07002630 MotionEntry* splitMotionEntry =
2631 new MotionEntry(originalMotionEntry->sequenceNum, originalMotionEntry->eventTime,
2632 originalMotionEntry->deviceId, originalMotionEntry->source,
2633 originalMotionEntry->displayId, originalMotionEntry->policyFlags,
2634 action, originalMotionEntry->actionButton, originalMotionEntry->flags,
2635 originalMotionEntry->metaState, originalMotionEntry->buttonState,
2636 originalMotionEntry->classification, originalMotionEntry->edgeFlags,
2637 originalMotionEntry->xPrecision, originalMotionEntry->yPrecision,
2638 originalMotionEntry->xCursorPosition,
2639 originalMotionEntry->yCursorPosition, originalMotionEntry->downTime,
2640 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002641
2642 if (originalMotionEntry->injectionState) {
2643 splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2644 splitMotionEntry->injectionState->refCount += 1;
2645 }
2646
2647 return splitMotionEntry;
2648}
2649
2650void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2651#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002652 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002653#endif
2654
2655 bool needWake;
2656 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002657 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002658
Prabir Pradhan42611e02018-11-27 14:04:02 -08002659 ConfigurationChangedEntry* newEntry =
2660 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002661 needWake = enqueueInboundEventLocked(newEntry);
2662 } // release lock
2663
2664 if (needWake) {
2665 mLooper->wake();
2666 }
2667}
2668
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002669/**
2670 * If one of the meta shortcuts is detected, process them here:
2671 * Meta + Backspace -> generate BACK
2672 * Meta + Enter -> generate HOME
2673 * This will potentially overwrite keyCode and metaState.
2674 */
2675void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
2676 int32_t& keyCode, int32_t& metaState) {
2677 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2678 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2679 if (keyCode == AKEYCODE_DEL) {
2680 newKeyCode = AKEYCODE_BACK;
2681 } else if (keyCode == AKEYCODE_ENTER) {
2682 newKeyCode = AKEYCODE_HOME;
2683 }
2684 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002685 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002686 struct KeyReplacement replacement = {keyCode, deviceId};
2687 mReplacedKeys.add(replacement, newKeyCode);
2688 keyCode = newKeyCode;
2689 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2690 }
2691 } else if (action == AKEY_EVENT_ACTION_UP) {
2692 // In order to maintain a consistent stream of up and down events, check to see if the key
2693 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2694 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002695 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002696 struct KeyReplacement replacement = {keyCode, deviceId};
2697 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2698 if (index >= 0) {
2699 keyCode = mReplacedKeys.valueAt(index);
2700 mReplacedKeys.removeItemsAt(index);
2701 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2702 }
2703 }
2704}
2705
Michael Wrightd02c5b62014-02-10 15:10:22 -08002706void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2707#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002708 ALOGD("notifyKey - eventTime=%" PRId64
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002709 ", deviceId=%d, source=0x%x, displayId=%" PRId32 "policyFlags=0x%x, action=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +08002710 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002711 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002712 args->action, args->flags, args->keyCode, args->scanCode,
Arthur Hung82a4cad2018-11-15 12:10:30 +08002713 args->metaState, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002714#endif
2715 if (!validateKeyEvent(args->action)) {
2716 return;
2717 }
2718
2719 uint32_t policyFlags = args->policyFlags;
2720 int32_t flags = args->flags;
2721 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002722 // InputDispatcher tracks and generates key repeats on behalf of
2723 // whatever notifies it, so repeatCount should always be set to 0
2724 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002725 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2726 policyFlags |= POLICY_FLAG_VIRTUAL;
2727 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2728 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002729 if (policyFlags & POLICY_FLAG_FUNCTION) {
2730 metaState |= AMETA_FUNCTION_ON;
2731 }
2732
2733 policyFlags |= POLICY_FLAG_TRUSTED;
2734
Michael Wright78f24442014-08-06 15:55:28 -07002735 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002736 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002737
Michael Wrightd02c5b62014-02-10 15:10:22 -08002738 KeyEvent event;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002739 event.initialize(args->deviceId, args->source, args->displayId, args->action,
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002740 flags, keyCode, args->scanCode, metaState, repeatCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002741 args->downTime, args->eventTime);
2742
Michael Wright2b3c3302018-03-02 17:19:13 +00002743 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002744 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002745 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2746 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2747 std::to_string(t.duration().count()).c_str());
2748 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002749
Michael Wrightd02c5b62014-02-10 15:10:22 -08002750 bool needWake;
2751 { // acquire lock
2752 mLock.lock();
2753
2754 if (shouldSendKeyToInputFilterLocked(args)) {
2755 mLock.unlock();
2756
2757 policyFlags |= POLICY_FLAG_FILTERED;
2758 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2759 return; // event was consumed by the filter
2760 }
2761
2762 mLock.lock();
2763 }
2764
Prabir Pradhan42611e02018-11-27 14:04:02 -08002765 KeyEntry* newEntry = new KeyEntry(args->sequenceNum, args->eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002766 args->deviceId, args->source, args->displayId, policyFlags,
Michael Wright78f24442014-08-06 15:55:28 -07002767 args->action, flags, keyCode, args->scanCode,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002768 metaState, repeatCount, args->downTime);
2769
2770 needWake = enqueueInboundEventLocked(newEntry);
2771 mLock.unlock();
2772 } // release lock
2773
2774 if (needWake) {
2775 mLooper->wake();
2776 }
2777}
2778
2779bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2780 return mInputFilterEnabled;
2781}
2782
2783void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2784#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002785 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07002786 ", policyFlags=0x%x, "
2787 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
2788 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07002789 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07002790 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2791 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
2792 args->edgeFlags, args->xPrecision, args->yPrecision, arg->xCursorPosition,
2793 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002794 for (uint32_t i = 0; i < args->pointerCount; i++) {
2795 ALOGD(" Pointer %d: id=%d, toolType=%d, "
2796 "x=%f, y=%f, pressure=%f, size=%f, "
2797 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2798 "orientation=%f",
2799 i, args->pointerProperties[i].id,
2800 args->pointerProperties[i].toolType,
2801 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2802 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2803 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2804 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2805 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2806 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2807 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2808 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2809 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2810 }
2811#endif
Michael Wright7b159c92015-05-14 14:48:03 +01002812 if (!validateMotionEvent(args->action, args->actionButton,
2813 args->pointerCount, args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002814 return;
2815 }
2816
2817 uint32_t policyFlags = args->policyFlags;
2818 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00002819
2820 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002821 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002822 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2823 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2824 std::to_string(t.duration().count()).c_str());
2825 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002826
2827 bool needWake;
2828 { // acquire lock
2829 mLock.lock();
2830
2831 if (shouldSendMotionToInputFilterLocked(args)) {
2832 mLock.unlock();
2833
2834 MotionEvent event;
Garfield Tan00f511d2019-06-12 16:55:40 -07002835 event.initialize(args->deviceId, args->source, args->displayId, args->action,
2836 args->actionButton, args->flags, args->edgeFlags, args->metaState,
2837 args->buttonState, args->classification, 0, 0, args->xPrecision,
2838 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2839 args->downTime, args->eventTime, args->pointerCount,
2840 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002841
2842 policyFlags |= POLICY_FLAG_FILTERED;
2843 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2844 return; // event was consumed by the filter
2845 }
2846
2847 mLock.lock();
2848 }
2849
2850 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002851 MotionEntry* newEntry =
2852 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2853 args->displayId, policyFlags, args->action, args->actionButton,
2854 args->flags, args->metaState, args->buttonState,
2855 args->classification, args->edgeFlags, args->xPrecision,
2856 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2857 args->downTime, args->pointerCount, args->pointerProperties,
2858 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002859
2860 needWake = enqueueInboundEventLocked(newEntry);
2861 mLock.unlock();
2862 } // release lock
2863
2864 if (needWake) {
2865 mLooper->wake();
2866 }
2867}
2868
2869bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08002870 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002871}
2872
2873void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2874#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002875 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
2876 "switchMask=0x%08x",
2877 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002878#endif
2879
2880 uint32_t policyFlags = args->policyFlags;
2881 policyFlags |= POLICY_FLAG_TRUSTED;
2882 mPolicy->notifySwitch(args->eventTime,
2883 args->switchValues, args->switchMask, policyFlags);
2884}
2885
2886void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
2887#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002888 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002889 args->eventTime, args->deviceId);
2890#endif
2891
2892 bool needWake;
2893 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002894 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002895
Prabir Pradhan42611e02018-11-27 14:04:02 -08002896 DeviceResetEntry* newEntry =
2897 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002898 needWake = enqueueInboundEventLocked(newEntry);
2899 } // release lock
2900
2901 if (needWake) {
2902 mLooper->wake();
2903 }
2904}
2905
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002906int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002907 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
2908 uint32_t policyFlags) {
2909#if DEBUG_INBOUND_EVENT_DETAILS
2910 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002911 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2912 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002913#endif
2914
2915 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2916
2917 policyFlags |= POLICY_FLAG_INJECTED;
2918 if (hasInjectionPermission(injectorPid, injectorUid)) {
2919 policyFlags |= POLICY_FLAG_TRUSTED;
2920 }
2921
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07002922 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002923 switch (event->getType()) {
2924 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002925 KeyEvent keyEvent;
2926 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
2927 int32_t action = keyEvent.getAction();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002928 if (! validateKeyEvent(action)) {
2929 return INPUT_EVENT_INJECTION_FAILED;
2930 }
2931
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002932 int32_t flags = keyEvent.getFlags();
2933 int32_t keyCode = keyEvent.getKeyCode();
2934 int32_t metaState = keyEvent.getMetaState();
2935 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
2936 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002937 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002938 action, flags, keyCode, keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002939 keyEvent.getDownTime(), keyEvent.getEventTime());
2940
Michael Wrightd02c5b62014-02-10 15:10:22 -08002941 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2942 policyFlags |= POLICY_FLAG_VIRTUAL;
2943 }
2944
2945 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wright2b3c3302018-03-02 17:19:13 +00002946 android::base::Timer t;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002947 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002948 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2949 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2950 std::to_string(t.duration().count()).c_str());
2951 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002952 }
2953
Michael Wrightd02c5b62014-02-10 15:10:22 -08002954 mLock.lock();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07002955 KeyEntry* injectedEntry =
2956 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
2957 keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
2958 policyFlags, action, flags, keyEvent.getKeyCode(),
2959 keyEvent.getScanCode(), keyEvent.getMetaState(),
2960 keyEvent.getRepeatCount(), keyEvent.getDownTime());
2961 injectedEntries.push(injectedEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002962 break;
2963 }
2964
2965 case AINPUT_EVENT_TYPE_MOTION: {
2966 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002967 int32_t action = motionEvent->getAction();
2968 size_t pointerCount = motionEvent->getPointerCount();
2969 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
Michael Wright7b159c92015-05-14 14:48:03 +01002970 int32_t actionButton = motionEvent->getActionButton();
Charles Chen3611f1f2019-01-29 17:26:18 +08002971 int32_t displayId = motionEvent->getDisplayId();
Michael Wright7b159c92015-05-14 14:48:03 +01002972 if (! validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002973 return INPUT_EVENT_INJECTION_FAILED;
2974 }
2975
2976 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2977 nsecs_t eventTime = motionEvent->getEventTime();
Michael Wright2b3c3302018-03-02 17:19:13 +00002978 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002979 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002980 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2981 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2982 std::to_string(t.duration().count()).c_str());
2983 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002984 }
2985
2986 mLock.lock();
2987 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2988 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07002989 MotionEntry* injectedEntry =
Garfield Tan00f511d2019-06-12 16:55:40 -07002990 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
2991 motionEvent->getDeviceId(), motionEvent->getSource(),
2992 motionEvent->getDisplayId(), policyFlags, action, actionButton,
2993 motionEvent->getFlags(), motionEvent->getMetaState(),
2994 motionEvent->getButtonState(), motionEvent->getClassification(),
2995 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
2996 motionEvent->getYPrecision(), motionEvent->getRawXCursorPosition(),
2997 motionEvent->getRawYCursorPosition(), motionEvent->getDownTime(),
2998 uint32_t(pointerCount), pointerProperties, samplePointerCoords,
2999 motionEvent->getXOffset(), motionEvent->getYOffset());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003000 injectedEntries.push(injectedEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003001 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3002 sampleEventTimes += 1;
3003 samplePointerCoords += pointerCount;
Garfield Tan00f511d2019-06-12 16:55:40 -07003004 MotionEntry* nextInjectedEntry =
3005 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3006 motionEvent->getDeviceId(), motionEvent->getSource(),
3007 motionEvent->getDisplayId(), policyFlags, action, actionButton,
3008 motionEvent->getFlags(), motionEvent->getMetaState(),
3009 motionEvent->getButtonState(), motionEvent->getClassification(),
3010 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3011 motionEvent->getYPrecision(),
3012 motionEvent->getRawXCursorPosition(),
3013 motionEvent->getRawYCursorPosition(),
3014 motionEvent->getDownTime(), uint32_t(pointerCount),
3015 pointerProperties, samplePointerCoords,
3016 motionEvent->getXOffset(), motionEvent->getYOffset());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003017 injectedEntries.push(nextInjectedEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003018 }
3019 break;
3020 }
3021
3022 default:
3023 ALOGW("Cannot inject event of type %d", event->getType());
3024 return INPUT_EVENT_INJECTION_FAILED;
3025 }
3026
3027 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3028 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3029 injectionState->injectionIsAsync = true;
3030 }
3031
3032 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003033 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003034
3035 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003036 while (!injectedEntries.empty()) {
3037 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3038 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003039 }
3040
3041 mLock.unlock();
3042
3043 if (needWake) {
3044 mLooper->wake();
3045 }
3046
3047 int32_t injectionResult;
3048 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003049 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003050
3051 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3052 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3053 } else {
3054 for (;;) {
3055 injectionResult = injectionState->injectionResult;
3056 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3057 break;
3058 }
3059
3060 nsecs_t remainingTimeout = endTime - now();
3061 if (remainingTimeout <= 0) {
3062#if DEBUG_INJECTION
3063 ALOGD("injectInputEvent - Timed out waiting for injection result "
3064 "to become available.");
3065#endif
3066 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3067 break;
3068 }
3069
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003070 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003071 }
3072
3073 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
3074 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
3075 while (injectionState->pendingForegroundDispatches != 0) {
3076#if DEBUG_INJECTION
3077 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
3078 injectionState->pendingForegroundDispatches);
3079#endif
3080 nsecs_t remainingTimeout = endTime - now();
3081 if (remainingTimeout <= 0) {
3082#if DEBUG_INJECTION
3083 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3084 "dispatches to finish.");
3085#endif
3086 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3087 break;
3088 }
3089
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003090 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003091 }
3092 }
3093 }
3094
3095 injectionState->release();
3096 } // release lock
3097
3098#if DEBUG_INJECTION
3099 ALOGD("injectInputEvent - Finished with result %d. "
3100 "injectorPid=%d, injectorUid=%d",
3101 injectionResult, injectorPid, injectorUid);
3102#endif
3103
3104 return injectionResult;
3105}
3106
3107bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
3108 return injectorUid == 0
3109 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
3110}
3111
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003112void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003113 InjectionState* injectionState = entry->injectionState;
3114 if (injectionState) {
3115#if DEBUG_INJECTION
3116 ALOGD("Setting input event injection result to %d. "
3117 "injectorPid=%d, injectorUid=%d",
3118 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
3119#endif
3120
3121 if (injectionState->injectionIsAsync
3122 && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
3123 // Log the outcome since the injector did not wait for the injection result.
3124 switch (injectionResult) {
3125 case INPUT_EVENT_INJECTION_SUCCEEDED:
3126 ALOGV("Asynchronous input event injection succeeded.");
3127 break;
3128 case INPUT_EVENT_INJECTION_FAILED:
3129 ALOGW("Asynchronous input event injection failed.");
3130 break;
3131 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3132 ALOGW("Asynchronous input event injection permission denied.");
3133 break;
3134 case INPUT_EVENT_INJECTION_TIMED_OUT:
3135 ALOGW("Asynchronous input event injection timed out.");
3136 break;
3137 }
3138 }
3139
3140 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003141 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003142 }
3143}
3144
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003145void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003146 InjectionState* injectionState = entry->injectionState;
3147 if (injectionState) {
3148 injectionState->pendingForegroundDispatches += 1;
3149 }
3150}
3151
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003152void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003153 InjectionState* injectionState = entry->injectionState;
3154 if (injectionState) {
3155 injectionState->pendingForegroundDispatches -= 1;
3156
3157 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003158 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003159 }
3160 }
3161}
3162
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003163std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3164 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003165 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003166}
3167
Michael Wrightd02c5b62014-02-10 15:10:22 -08003168sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003169 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003170 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003171 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3172 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003173 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003174 return windowHandle;
3175 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003176 }
3177 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003178 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003179}
3180
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003181bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003182 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003183 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3184 for (const sp<InputWindowHandle>& handle : windowHandles) {
3185 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003186 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003187 ALOGE("Found window %s in display %" PRId32
3188 ", but it should belong to display %" PRId32,
3189 windowHandle->getName().c_str(), it.first,
3190 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003191 }
3192 return true;
3193 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003194 }
3195 }
3196 return false;
3197}
3198
Robert Carr5c8a0262018-10-03 16:30:44 -07003199sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3200 size_t count = mInputChannelsByToken.count(token);
3201 if (count == 0) {
3202 return nullptr;
3203 }
3204 return mInputChannelsByToken.at(token);
3205}
3206
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003207void InputDispatcher::updateWindowHandlesForDisplayLocked(
3208 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3209 if (inputWindowHandles.empty()) {
3210 // Remove all handles on a display if there are no windows left.
3211 mWindowHandlesByDisplay.erase(displayId);
3212 return;
3213 }
3214
3215 // Since we compare the pointer of input window handles across window updates, we need
3216 // to make sure the handle object for the same window stays unchanged across updates.
3217 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
3218 std::unordered_map<sp<IBinder>, sp<InputWindowHandle>, IBinderHash> oldHandlesByTokens;
3219 for (const sp<InputWindowHandle>& handle : oldHandles) {
3220 oldHandlesByTokens[handle->getToken()] = handle;
3221 }
3222
3223 std::vector<sp<InputWindowHandle>> newHandles;
3224 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3225 if (!handle->updateInfo()) {
3226 // handle no longer valid
3227 continue;
3228 }
3229
3230 const InputWindowInfo* info = handle->getInfo();
3231 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3232 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3233 const bool noInputChannel =
3234 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3235 const bool canReceiveInput =
3236 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3237 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3238 if (canReceiveInput && !noInputChannel) {
3239 ALOGE("Window handle %s has no registered input channel",
3240 handle->getName().c_str());
3241 }
3242 continue;
3243 }
3244
3245 if (info->displayId != displayId) {
3246 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3247 handle->getName().c_str(), displayId, info->displayId);
3248 continue;
3249 }
3250
3251 if (oldHandlesByTokens.find(handle->getToken()) != oldHandlesByTokens.end()) {
3252 const sp<InputWindowHandle> oldHandle = oldHandlesByTokens.at(handle->getToken());
3253 oldHandle->updateFrom(handle);
3254 newHandles.push_back(oldHandle);
3255 } else {
3256 newHandles.push_back(handle);
3257 }
3258 }
3259
3260 // Insert or replace
3261 mWindowHandlesByDisplay[displayId] = newHandles;
3262}
3263
Arthur Hungb92218b2018-08-14 12:00:21 +08003264/**
3265 * Called from InputManagerService, update window handle list by displayId that can receive input.
3266 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3267 * If set an empty list, remove all handles from the specific display.
3268 * For focused handle, check if need to change and send a cancel event to previous one.
3269 * For removed handle, check if need to send a cancel event if already in touch.
3270 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003271void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
chaviw291d88a2019-02-14 10:33:58 -08003272 int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003273#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003274 ALOGD("setInputWindows displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003275#endif
3276 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003277 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003278
Arthur Hungb92218b2018-08-14 12:00:21 +08003279 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003280 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3281 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003282
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003283 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3284
Tiger Huang721e26f2018-07-24 22:26:19 +08003285 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003286 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003287 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3288 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3289 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3290 windowHandle->getInfo()->visible) {
3291 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003292 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003293 if (windowHandle == mLastHoverWindowHandle) {
3294 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003295 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003296 }
3297
3298 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003299 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003300 }
3301
Tiger Huang721e26f2018-07-24 22:26:19 +08003302 sp<InputWindowHandle> oldFocusedWindowHandle =
3303 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3304
3305 if (oldFocusedWindowHandle != newFocusedWindowHandle) {
3306 if (oldFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003307#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003308 ALOGD("Focus left window: %s in display %" PRId32,
3309 oldFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003310#endif
Robert Carr5c8a0262018-10-03 16:30:44 -07003311 sp<InputChannel> focusedInputChannel = getInputChannelLocked(
3312 oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003313 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003314 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3315 "focus left window");
3316 synthesizeCancelationEventsForInputChannelLocked(
3317 focusedInputChannel, options);
3318 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003319 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003320 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003321 if (newFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003322#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003323 ALOGD("Focus entered window: %s in display %" PRId32,
3324 newFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003325#endif
Tiger Huang721e26f2018-07-24 22:26:19 +08003326 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327 }
Robert Carrf759f162018-11-13 12:57:11 -08003328
3329 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003330 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003331 }
3332
Michael Wrightd02c5b62014-02-10 15:10:22 -08003333 }
3334
Arthur Hungb92218b2018-08-14 12:00:21 +08003335 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3336 if (stateIndex >= 0) {
3337 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Ivan Lozano96f12992017-11-09 14:45:38 -08003338 for (size_t i = 0; i < state.windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003339 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003340 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003341#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003342 ALOGD("Touched window was removed: %s in display %" PRId32,
3343 touchedWindow.windowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003344#endif
Jeff Brownf086ddb2014-02-11 14:28:48 -08003345 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003346 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003347 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003348 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3349 "touched window was removed");
3350 synthesizeCancelationEventsForInputChannelLocked(
3351 touchedInputChannel, options);
3352 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003353 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003354 } else {
3355 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003356 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003357 }
3358 }
3359
3360 // Release information for windows that are no longer present.
3361 // This ensures that unused input channels are released promptly.
3362 // Otherwise, they might stick around until the window handle is destroyed
3363 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003364 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003365 if (!hasWindowHandleLocked(oldWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003366#if DEBUG_FOCUS
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003367 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003368#endif
Arthur Hung3b413f22018-10-26 18:05:34 +08003369 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003370 }
3371 }
3372 } // release lock
3373
3374 // Wake up poll loop since it may need to make new input dispatching choices.
3375 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003376
3377 if (setInputWindowsListener) {
3378 setInputWindowsListener->onSetInputWindowsFinished();
3379 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003380}
3381
3382void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003383 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003384#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003385 ALOGD("setFocusedApplication displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003386#endif
3387 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003388 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003389
Tiger Huang721e26f2018-07-24 22:26:19 +08003390 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3391 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003392 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003393 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3394 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003395 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003396 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003397 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003398 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003399 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003400 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003401 oldFocusedApplicationHandle.clear();
3402 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003403 }
3404
3405#if DEBUG_FOCUS
3406 //logDispatchStateLocked();
3407#endif
3408 } // release lock
3409
3410 // Wake up poll loop since it may need to make new input dispatching choices.
3411 mLooper->wake();
3412}
3413
Tiger Huang721e26f2018-07-24 22:26:19 +08003414/**
3415 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3416 * the display not specified.
3417 *
3418 * We track any unreleased events for each window. If a window loses the ability to receive the
3419 * released event, we will send a cancel event to it. So when the focused display is changed, we
3420 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3421 * display. The display-specified events won't be affected.
3422 */
3423void InputDispatcher::setFocusedDisplay(int32_t displayId) {
3424#if DEBUG_FOCUS
3425 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3426#endif
3427 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003428 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003429
3430 if (mFocusedDisplayId != displayId) {
3431 sp<InputWindowHandle> oldFocusedWindowHandle =
3432 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3433 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003434 sp<InputChannel> inputChannel =
3435 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003436 if (inputChannel != nullptr) {
3437 CancelationOptions options(
Michael Wright3dd60e22019-03-27 22:06:44 +00003438 CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Tiger Huang721e26f2018-07-24 22:26:19 +08003439 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003440 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003441 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3442 }
3443 }
3444 mFocusedDisplayId = displayId;
3445
3446 // Sanity check
3447 sp<InputWindowHandle> newFocusedWindowHandle =
3448 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003449 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003450
Tiger Huang721e26f2018-07-24 22:26:19 +08003451 if (newFocusedWindowHandle == nullptr) {
3452 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3453 if (!mFocusedWindowHandlesByDisplay.empty()) {
3454 ALOGE("But another display has a focused window:");
3455 for (auto& it : mFocusedWindowHandlesByDisplay) {
3456 const int32_t displayId = it.first;
3457 const sp<InputWindowHandle>& windowHandle = it.second;
3458 ALOGE("Display #%" PRId32 " has focused window: '%s'\n",
3459 displayId, windowHandle->getName().c_str());
3460 }
3461 }
3462 }
3463 }
3464
3465#if DEBUG_FOCUS
3466 logDispatchStateLocked();
3467#endif
3468 } // release lock
3469
3470 // Wake up poll loop since it may need to make new input dispatching choices.
3471 mLooper->wake();
3472}
3473
Michael Wrightd02c5b62014-02-10 15:10:22 -08003474void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
3475#if DEBUG_FOCUS
3476 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3477#endif
3478
3479 bool changed;
3480 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003481 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003482
3483 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3484 if (mDispatchFrozen && !frozen) {
3485 resetANRTimeoutsLocked();
3486 }
3487
3488 if (mDispatchEnabled && !enabled) {
3489 resetAndDropEverythingLocked("dispatcher is being disabled");
3490 }
3491
3492 mDispatchEnabled = enabled;
3493 mDispatchFrozen = frozen;
3494 changed = true;
3495 } else {
3496 changed = false;
3497 }
3498
3499#if DEBUG_FOCUS
Tiger Huang721e26f2018-07-24 22:26:19 +08003500 logDispatchStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003501#endif
3502 } // release lock
3503
3504 if (changed) {
3505 // Wake up poll loop since it may need to make new input dispatching choices.
3506 mLooper->wake();
3507 }
3508}
3509
3510void InputDispatcher::setInputFilterEnabled(bool enabled) {
3511#if DEBUG_FOCUS
3512 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3513#endif
3514
3515 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003516 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003517
3518 if (mInputFilterEnabled == enabled) {
3519 return;
3520 }
3521
3522 mInputFilterEnabled = enabled;
3523 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3524 } // release lock
3525
3526 // Wake up poll loop since there might be work to do to drop everything.
3527 mLooper->wake();
3528}
3529
chaviwfbe5d9c2018-12-26 12:23:37 -08003530bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3531 if (fromToken == toToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003532#if DEBUG_FOCUS
chaviwfbe5d9c2018-12-26 12:23:37 -08003533 ALOGD("Trivial transfer to same window.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003534#endif
chaviwfbe5d9c2018-12-26 12:23:37 -08003535 return true;
3536 }
3537
Michael Wrightd02c5b62014-02-10 15:10:22 -08003538 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003539 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003540
chaviwfbe5d9c2018-12-26 12:23:37 -08003541 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3542 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003543 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003544 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003545 return false;
3546 }
chaviw4f2dd402018-12-26 15:30:27 -08003547#if DEBUG_FOCUS
3548 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3549 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3550#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003551 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
3552#if DEBUG_FOCUS
3553 ALOGD("Cannot transfer focus because windows are on different displays.");
3554#endif
3555 return false;
3556 }
3557
3558 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003559 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3560 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3561 for (size_t i = 0; i < state.windows.size(); i++) {
3562 const TouchedWindow& touchedWindow = state.windows[i];
3563 if (touchedWindow.windowHandle == fromWindowHandle) {
3564 int32_t oldTargetFlags = touchedWindow.targetFlags;
3565 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003566
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003567 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003568
Jeff Brownf086ddb2014-02-11 14:28:48 -08003569 int32_t newTargetFlags = oldTargetFlags
3570 & (InputTarget::FLAG_FOREGROUND
3571 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
3572 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003573
Jeff Brownf086ddb2014-02-11 14:28:48 -08003574 found = true;
3575 goto Found;
3576 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003577 }
3578 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003579Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003580
3581 if (! found) {
3582#if DEBUG_FOCUS
3583 ALOGD("Focus transfer failed because from window did not have focus.");
3584#endif
3585 return false;
3586 }
3587
chaviwfbe5d9c2018-12-26 12:23:37 -08003588
3589 sp<InputChannel> fromChannel = getInputChannelLocked(fromToken);
3590 sp<InputChannel> toChannel = getInputChannelLocked(toToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003591 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
3592 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
3593 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
3594 sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
3595 sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
3596
3597 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
3598 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3599 "transferring touch focus from this window to another window");
3600 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
3601 }
3602
3603#if DEBUG_FOCUS
3604 logDispatchStateLocked();
3605#endif
3606 } // release lock
3607
3608 // Wake up poll loop since it may need to make new input dispatching choices.
3609 mLooper->wake();
3610 return true;
3611}
3612
3613void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
3614#if DEBUG_FOCUS
3615 ALOGD("Resetting and dropping all events (%s).", reason);
3616#endif
3617
3618 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3619 synthesizeCancelationEventsForAllConnectionsLocked(options);
3620
3621 resetKeyRepeatLocked();
3622 releasePendingEventLocked();
3623 drainInboundQueueLocked();
3624 resetANRTimeoutsLocked();
3625
Jeff Brownf086ddb2014-02-11 14:28:48 -08003626 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003627 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003628 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003629}
3630
3631void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003632 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003633 dumpDispatchStateLocked(dump);
3634
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003635 std::istringstream stream(dump);
3636 std::string line;
3637
3638 while (std::getline(stream, line, '\n')) {
3639 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003640 }
3641}
3642
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003643void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003644 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3645 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3646 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003647 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003648
Tiger Huang721e26f2018-07-24 22:26:19 +08003649 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3650 dump += StringPrintf(INDENT "FocusedApplications:\n");
3651 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3652 const int32_t displayId = it.first;
3653 const sp<InputApplicationHandle>& applicationHandle = it.second;
3654 dump += StringPrintf(
3655 INDENT2 "displayId=%" PRId32 ", name='%s', dispatchingTimeout=%0.3fms\n",
3656 displayId,
3657 applicationHandle->getName().c_str(),
3658 applicationHandle->getDispatchingTimeout(
3659 DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
3660 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003661 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003662 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003663 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003664
3665 if (!mFocusedWindowHandlesByDisplay.empty()) {
3666 dump += StringPrintf(INDENT "FocusedWindows:\n");
3667 for (auto& it : mFocusedWindowHandlesByDisplay) {
3668 const int32_t displayId = it.first;
3669 const sp<InputWindowHandle>& windowHandle = it.second;
3670 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n",
3671 displayId, windowHandle->getName().c_str());
3672 }
3673 } else {
3674 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3675 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003676
Jeff Brownf086ddb2014-02-11 14:28:48 -08003677 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003678 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003679 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3680 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003681 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Jeff Brownf086ddb2014-02-11 14:28:48 -08003682 state.displayId, toString(state.down), toString(state.split),
3683 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003684 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003685 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003686 for (size_t i = 0; i < state.windows.size(); i++) {
3687 const TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003688 dump += StringPrintf(INDENT4 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3689 i, touchedWindow.windowHandle->getName().c_str(),
Jeff Brownf086ddb2014-02-11 14:28:48 -08003690 touchedWindow.pointerIds.value,
3691 touchedWindow.targetFlags);
3692 }
3693 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003694 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003695 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003696 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003697 dump += INDENT3 "Portal windows:\n";
3698 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003699 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003700 dump += StringPrintf(INDENT4 "%zu: name='%s'\n",
3701 i, portalWindowHandle->getName().c_str());
3702 }
3703 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003704 }
3705 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003706 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003707 }
3708
Arthur Hungb92218b2018-08-14 12:00:21 +08003709 if (!mWindowHandlesByDisplay.empty()) {
3710 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003711 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003712 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003713 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003714 dump += INDENT2 "Windows:\n";
3715 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003716 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003717 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003718
Arthur Hungb92218b2018-08-14 12:00:21 +08003719 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003720 "portalToDisplayId=%d, paused=%s, hasFocus=%s, hasWallpaper=%s, "
Arthur Hungb92218b2018-08-14 12:00:21 +08003721 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
Riddle Hsu39d4aa52018-11-30 20:46:53 +08003722 "frame=[%d,%d][%d,%d], globalScale=%f, windowScale=(%f,%f), "
Arthur Hungb92218b2018-08-14 12:00:21 +08003723 "touchableRegion=",
3724 i, windowInfo->name.c_str(), windowInfo->displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003725 windowInfo->portalToDisplayId,
Arthur Hungb92218b2018-08-14 12:00:21 +08003726 toString(windowInfo->paused),
3727 toString(windowInfo->hasFocus),
3728 toString(windowInfo->hasWallpaper),
3729 toString(windowInfo->visible),
3730 toString(windowInfo->canReceiveKeys),
3731 windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
3732 windowInfo->layer,
3733 windowInfo->frameLeft, windowInfo->frameTop,
3734 windowInfo->frameRight, windowInfo->frameBottom,
Robert Carre07e1032018-11-26 12:55:53 -08003735 windowInfo->globalScaleFactor,
3736 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003737 dumpRegion(dump, windowInfo->touchableRegion);
3738 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3739 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
3740 windowInfo->ownerPid, windowInfo->ownerUid,
3741 windowInfo->dispatchingTimeout / 1000000.0);
3742 }
3743 } else {
3744 dump += INDENT2 "Windows: <none>\n";
3745 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003746 }
3747 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003748 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003749 }
3750
Michael Wright3dd60e22019-03-27 22:06:44 +00003751 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
3752 for (auto& it : mGlobalMonitorsByDisplay) {
3753 const std::vector<Monitor>& monitors = it.second;
3754 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3755 dumpMonitors(dump, monitors);
3756 }
3757 for (auto& it : mGestureMonitorsByDisplay) {
3758 const std::vector<Monitor>& monitors = it.second;
3759 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
3760 dumpMonitors(dump, monitors);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003761 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003762 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00003763 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003764 }
3765
3766 nsecs_t currentTime = now();
3767
3768 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003769 if (!mRecentQueue.empty()) {
3770 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
3771 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003772 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003773 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003774 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003775 (currentTime - entry->eventTime) * 0.000001f);
3776 }
3777 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003778 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003779 }
3780
3781 // Dump event currently being dispatched.
3782 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003783 dump += INDENT "PendingEvent:\n";
3784 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003785 mPendingEvent->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 - mPendingEvent->eventTime) * 0.000001f);
3788 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003789 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003790 }
3791
3792 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003793 if (!mInboundQueue.empty()) {
3794 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
3795 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003796 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003797 entry->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 - entry->eventTime) * 0.000001f);
3800 }
3801 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003802 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003803 }
3804
Michael Wright78f24442014-08-06 15:55:28 -07003805 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003806 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07003807 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
3808 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
3809 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003810 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n",
Michael Wright78f24442014-08-06 15:55:28 -07003811 i, replacement.keyCode, replacement.deviceId, newKeyCode);
3812 }
3813 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003814 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07003815 }
3816
Michael Wrightd02c5b62014-02-10 15:10:22 -08003817 if (!mConnectionsByFd.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003818 dump += INDENT "Connections:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003819 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
3820 const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003821 dump += StringPrintf(INDENT2 "%zu: channelName='%s', windowName='%s', "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003822 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08003823 i, connection->getInputChannelName().c_str(),
3824 connection->getWindowName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08003825 connection->getStatusLabel(), toString(connection->monitor),
3826 toString(connection->inputPublisherBlocked));
3827
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003828 if (!connection->outboundQueue.empty()) {
3829 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
3830 connection->outboundQueue.size());
3831 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003832 dump.append(INDENT4);
3833 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003834 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003835 entry->targetFlags, entry->resolvedAction,
3836 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
3837 }
3838 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003839 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003840 }
3841
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003842 if (!connection->waitQueue.empty()) {
3843 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
3844 connection->waitQueue.size());
3845 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003846 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003847 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003848 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003849 "age=%0.1fms, wait=%0.1fms\n",
3850 entry->targetFlags, entry->resolvedAction,
3851 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
3852 (currentTime - entry->deliveryTime) * 0.000001f);
3853 }
3854 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003855 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003856 }
3857 }
3858 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003859 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003860 }
3861
3862 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003863 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003864 (mAppSwitchDueTime - now()) / 1000000.0);
3865 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003866 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003867 }
3868
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003869 dump += INDENT "Configuration:\n";
3870 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003871 mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003872 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003873 mConfig.keyRepeatTimeout * 0.000001f);
3874}
3875
Michael Wright3dd60e22019-03-27 22:06:44 +00003876void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
3877 const size_t numMonitors = monitors.size();
3878 for (size_t i = 0; i < numMonitors; i++) {
3879 const Monitor& monitor = monitors[i];
3880 const sp<InputChannel>& channel = monitor.inputChannel;
3881 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
3882 dump += "\n";
3883 }
3884}
3885
3886status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3887 int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003888#if DEBUG_REGISTRATION
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003889 ALOGD("channel '%s' ~ registerInputChannel - displayId=%" PRId32,
3890 inputChannel->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003891#endif
3892
3893 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003894 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003895
3896 if (getConnectionIndexLocked(inputChannel) >= 0) {
3897 ALOGW("Attempted to register already registered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003898 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003899 return BAD_VALUE;
3900 }
3901
Michael Wright3dd60e22019-03-27 22:06:44 +00003902 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003903
3904 int fd = inputChannel->getFd();
3905 mConnectionsByFd.add(fd, connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07003906 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003907
Michael Wrightd02c5b62014-02-10 15:10:22 -08003908 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3909 } // release lock
3910
3911 // Wake the looper because some connections have changed.
3912 mLooper->wake();
3913 return OK;
3914}
3915
Michael Wright3dd60e22019-03-27 22:06:44 +00003916status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
3917 int32_t displayId, bool isGestureMonitor) {
3918 { // acquire lock
3919 std::scoped_lock _l(mLock);
3920
3921 if (displayId < 0) {
3922 ALOGW("Attempted to register input monitor without a specified display.");
3923 return BAD_VALUE;
3924 }
3925
3926 if (inputChannel->getToken() == nullptr) {
3927 ALOGW("Attempted to register input monitor without an identifying token.");
3928 return BAD_VALUE;
3929 }
3930
3931 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
3932
3933 const int fd = inputChannel->getFd();
3934 mConnectionsByFd.add(fd, connection);
3935 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
3936
3937 auto& monitorsByDisplay = isGestureMonitor
3938 ? mGestureMonitorsByDisplay
3939 : mGlobalMonitorsByDisplay;
3940 monitorsByDisplay[displayId].emplace_back(inputChannel);
3941
3942 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3943
3944 }
3945 // Wake the looper because some connections have changed.
3946 mLooper->wake();
3947 return OK;
3948}
3949
Michael Wrightd02c5b62014-02-10 15:10:22 -08003950status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
3951#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003952 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003953#endif
3954
3955 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003956 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003957
3958 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3959 if (status) {
3960 return status;
3961 }
3962 } // release lock
3963
3964 // Wake the poll loop because removing the connection may have changed the current
3965 // synchronization state.
3966 mLooper->wake();
3967 return OK;
3968}
3969
3970status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
3971 bool notify) {
3972 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
3973 if (connectionIndex < 0) {
3974 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003975 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976 return BAD_VALUE;
3977 }
3978
3979 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
3980 mConnectionsByFd.removeItemsAt(connectionIndex);
3981
Robert Carr5c8a0262018-10-03 16:30:44 -07003982 mInputChannelsByToken.erase(inputChannel->getToken());
3983
Michael Wrightd02c5b62014-02-10 15:10:22 -08003984 if (connection->monitor) {
3985 removeMonitorChannelLocked(inputChannel);
3986 }
3987
3988 mLooper->removeFd(inputChannel->getFd());
3989
3990 nsecs_t currentTime = now();
3991 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
3992
3993 connection->status = Connection::STATUS_ZOMBIE;
3994 return OK;
3995}
3996
3997void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003998 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
3999 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4000}
4001
4002void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel,
4003 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
4004 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end(); ) {
4005 std::vector<Monitor>& monitors = it->second;
4006 const size_t numMonitors = monitors.size();
4007 for (size_t i = 0; i < numMonitors; i++) {
4008 if (monitors[i].inputChannel == inputChannel) {
4009 monitors.erase(monitors.begin() + i);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004010 break;
4011 }
4012 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004013 if (monitors.empty()) {
4014 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004015 } else {
4016 ++it;
4017 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004018 }
4019}
4020
Michael Wright3dd60e22019-03-27 22:06:44 +00004021status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4022 { // acquire lock
4023 std::scoped_lock _l(mLock);
4024 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4025
4026 if (!foundDisplayId) {
4027 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4028 return BAD_VALUE;
4029 }
4030 int32_t displayId = foundDisplayId.value();
4031
4032 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4033 if (stateIndex < 0) {
4034 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4035 return BAD_VALUE;
4036 }
4037
4038 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4039 std::optional<int32_t> foundDeviceId;
4040 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
4041 if (touchedMonitor.monitor.inputChannel->getToken() == token) {
4042 foundDeviceId = state.deviceId;
4043 }
4044 }
4045 if (!foundDeviceId || !state.down) {
4046 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
4047 " Ignoring.");
4048 return BAD_VALUE;
4049 }
4050 int32_t deviceId = foundDeviceId.value();
4051
4052 // Send cancel events to all the input channels we're stealing from.
4053 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4054 "gesture monitor stole pointer stream");
4055 options.deviceId = deviceId;
4056 options.displayId = displayId;
4057 for (const TouchedWindow& window : state.windows) {
4058 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
4059 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4060 }
4061 // Then clear the current touch state so we stop dispatching to them as well.
4062 state.filterNonMonitors();
4063 }
4064 return OK;
4065}
4066
4067
4068std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4069 const sp<IBinder>& token) {
4070 for (const auto& it : mGestureMonitorsByDisplay) {
4071 const std::vector<Monitor>& monitors = it.second;
4072 for (const Monitor& monitor : monitors) {
4073 if (monitor.inputChannel->getToken() == token) {
4074 return it.first;
4075 }
4076 }
4077 }
4078 return std::nullopt;
4079}
4080
Michael Wrightd02c5b62014-02-10 15:10:22 -08004081ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Robert Carr4e670e52018-08-15 13:26:12 -07004082 if (inputChannel == nullptr) {
Arthur Hung3b413f22018-10-26 18:05:34 +08004083 return -1;
4084 }
4085
Robert Carr4e670e52018-08-15 13:26:12 -07004086 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
4087 sp<Connection> connection = mConnectionsByFd.valueAt(i);
4088 if (connection->inputChannel->getToken() == inputChannel->getToken()) {
4089 return i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004090 }
4091 }
Robert Carr4e670e52018-08-15 13:26:12 -07004092
Michael Wrightd02c5b62014-02-10 15:10:22 -08004093 return -1;
4094}
4095
4096void InputDispatcher::onDispatchCycleFinishedLocked(
4097 nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07004098 CommandEntry* commandEntry =
4099 postCommandLocked(&InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004100 commandEntry->connection = connection;
4101 commandEntry->eventTime = currentTime;
4102 commandEntry->seq = seq;
4103 commandEntry->handled = handled;
4104}
4105
4106void InputDispatcher::onDispatchCycleBrokenLocked(
4107 nsecs_t currentTime, const sp<Connection>& connection) {
4108 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004109 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004110
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07004111 CommandEntry* commandEntry =
4112 postCommandLocked(&InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004113 commandEntry->connection = connection;
4114}
4115
chaviw0c06c6e2019-01-09 13:27:07 -08004116void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
4117 const sp<InputWindowHandle>& newFocus) {
4118 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4119 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07004120 CommandEntry* commandEntry =
4121 postCommandLocked(&InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004122 commandEntry->oldToken = oldToken;
4123 commandEntry->newToken = newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004124}
4125
Michael Wrightd02c5b62014-02-10 15:10:22 -08004126void InputDispatcher::onANRLocked(
4127 nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
4128 const sp<InputWindowHandle>& windowHandle,
4129 nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
4130 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4131 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4132 ALOGI("Application is not responding: %s. "
4133 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004134 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004135 dispatchLatency, waitDuration, reason);
4136
4137 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004138 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004139 struct tm tm;
4140 localtime_r(&t, &tm);
4141 char timestr[64];
4142 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4143 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004144 mLastANRState += INDENT "ANR:\n";
4145 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
4146 mLastANRState += StringPrintf(INDENT2 "Window: %s\n",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004147 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004148 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4149 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4150 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004151 dumpDispatchStateLocked(mLastANRState);
4152
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07004153 CommandEntry* commandEntry =
4154 postCommandLocked(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004155 commandEntry->inputApplicationHandle = applicationHandle;
Robert Carr5c8a0262018-10-03 16:30:44 -07004156 commandEntry->inputChannel = windowHandle != nullptr ?
4157 getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004158 commandEntry->reason = reason;
4159}
4160
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004161void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible (
Michael Wrightd02c5b62014-02-10 15:10:22 -08004162 CommandEntry* commandEntry) {
4163 mLock.unlock();
4164
4165 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4166
4167 mLock.lock();
4168}
4169
4170void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
4171 CommandEntry* commandEntry) {
4172 sp<Connection> connection = commandEntry->connection;
4173
4174 if (connection->status != Connection::STATUS_ZOMBIE) {
4175 mLock.unlock();
4176
Robert Carr803535b2018-08-02 16:38:15 -07004177 mPolicy->notifyInputChannelBroken(connection->inputChannel->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004178
4179 mLock.lock();
4180 }
4181}
4182
Robert Carrf759f162018-11-13 12:57:11 -08004183void InputDispatcher::doNotifyFocusChangedLockedInterruptible(
4184 CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004185 sp<IBinder> oldToken = commandEntry->oldToken;
4186 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004187 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004188 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004189 mLock.lock();
4190}
4191
Michael Wrightd02c5b62014-02-10 15:10:22 -08004192void InputDispatcher::doNotifyANRLockedInterruptible(
4193 CommandEntry* commandEntry) {
4194 mLock.unlock();
4195
4196 nsecs_t newTimeout = mPolicy->notifyANR(
Robert Carr803535b2018-08-02 16:38:15 -07004197 commandEntry->inputApplicationHandle,
4198 commandEntry->inputChannel ? commandEntry->inputChannel->getToken() : nullptr,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004199 commandEntry->reason);
4200
4201 mLock.lock();
4202
4203 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
Robert Carr803535b2018-08-02 16:38:15 -07004204 commandEntry->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004205}
4206
4207void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4208 CommandEntry* commandEntry) {
4209 KeyEntry* entry = commandEntry->keyEntry;
4210
4211 KeyEvent event;
4212 initializeKeyEvent(&event, entry);
4213
4214 mLock.unlock();
4215
Michael Wright2b3c3302018-03-02 17:19:13 +00004216 android::base::Timer t;
Robert Carr803535b2018-08-02 16:38:15 -07004217 sp<IBinder> token = commandEntry->inputChannel != nullptr ?
4218 commandEntry->inputChannel->getToken() : nullptr;
4219 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004220 &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004221 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4222 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
4223 std::to_string(t.duration().count()).c_str());
4224 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004225
4226 mLock.lock();
4227
4228 if (delay < 0) {
4229 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4230 } else if (!delay) {
4231 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4232 } else {
4233 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4234 entry->interceptKeyWakeupTime = now() + delay;
4235 }
4236 entry->release();
4237}
4238
chaviwfd6d3512019-03-25 13:23:49 -07004239void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4240 mLock.unlock();
4241 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4242 mLock.lock();
4243}
4244
Michael Wrightd02c5b62014-02-10 15:10:22 -08004245void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
4246 CommandEntry* commandEntry) {
4247 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004248 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004249 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004250 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004251
4252 // Handle post-event policy actions.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004253 std::deque<InputDispatcher::DispatchEntry*>::iterator dispatchEntryIt =
4254 connection->findWaitQueueEntry(seq);
4255 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004256 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004257 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004258 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004259
4260 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4261 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4262 std::string msg =
4263 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4264 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4265 dispatchEntry->eventEntry->appendDescription(msg);
4266 ALOGI("%s", msg.c_str());
4267 }
4268
4269 bool restartEvent;
4270 if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
4271 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4272 restartEvent =
4273 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
4274 } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
4275 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4276 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4277 handled);
4278 } else {
4279 restartEvent = false;
4280 }
4281
4282 // Dequeue the event and start the next cycle.
4283 // Note that because the lock might have been released, it is possible that the
4284 // contents of the wait queue to have been drained, so we need to double-check
4285 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004286 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4287 if (dispatchEntryIt != connection->waitQueue.end()) {
4288 dispatchEntry = *dispatchEntryIt;
4289 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004290 traceWaitQueueLength(connection);
4291 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004292 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004293 traceOutboundQueueLength(connection);
4294 } else {
4295 releaseDispatchEntry(dispatchEntry);
4296 }
4297 }
4298
4299 // Start the next dispatch cycle for this connection.
4300 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004301}
4302
4303bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
4304 DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004305 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004306 if (!handled) {
4307 // Report the key as unhandled, since the fallback was not handled.
4308 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4309 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004310 return false;
4311 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004312
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004313 // Get the fallback key state.
4314 // Clear it out after dispatching the UP.
4315 int32_t originalKeyCode = keyEntry->keyCode;
4316 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4317 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4318 connection->inputState.removeFallbackKey(originalKeyCode);
4319 }
4320
4321 if (handled || !dispatchEntry->hasForegroundTarget()) {
4322 // If the application handles the original key for which we previously
4323 // generated a fallback or if the window is not a foreground window,
4324 // then cancel the associated fallback key, if any.
4325 if (fallbackKeyCode != -1) {
4326 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004327#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004328 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004329 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4330 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4331 keyEntry->policyFlags);
4332#endif
4333 KeyEvent event;
4334 initializeKeyEvent(&event, keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004335 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004336
4337 mLock.unlock();
4338
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004339 mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4340 &event, keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004341
4342 mLock.lock();
4343
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004344 // Cancel the fallback key.
4345 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004346 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004347 "application handled the original non-fallback key "
4348 "or is no longer a foreground target, "
4349 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004350 options.keyCode = fallbackKeyCode;
4351 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004352 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004353 connection->inputState.removeFallbackKey(originalKeyCode);
4354 }
4355 } else {
4356 // If the application did not handle a non-fallback key, first check
4357 // that we are in a good state to perform unhandled key event processing
4358 // Then ask the policy what to do with it.
4359 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
4360 && keyEntry->repeatCount == 0;
4361 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004362#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004363 ALOGD("Unhandled key event: Skipping unhandled key event processing "
4364 "since this is not an initial down. "
4365 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4366 originalKeyCode, keyEntry->action, keyEntry->repeatCount,
4367 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004368#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004369 return false;
4370 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004371
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004372 // Dispatch the unhandled key to the policy.
4373#if DEBUG_OUTBOUND_EVENT_DETAILS
4374 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
4375 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4376 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4377 keyEntry->policyFlags);
4378#endif
4379 KeyEvent event;
4380 initializeKeyEvent(&event, keyEntry);
4381
4382 mLock.unlock();
4383
4384 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4385 &event, keyEntry->policyFlags, &event);
4386
4387 mLock.lock();
4388
4389 if (connection->status != Connection::STATUS_NORMAL) {
4390 connection->inputState.removeFallbackKey(originalKeyCode);
4391 return false;
4392 }
4393
4394 // Latch the fallback keycode for this key on an initial down.
4395 // The fallback keycode cannot change at any other point in the lifecycle.
4396 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004397 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004398 fallbackKeyCode = event.getKeyCode();
4399 } else {
4400 fallbackKeyCode = AKEYCODE_UNKNOWN;
4401 }
4402 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4403 }
4404
4405 ALOG_ASSERT(fallbackKeyCode != -1);
4406
4407 // Cancel the fallback key if the policy decides not to send it anymore.
4408 // We will continue to dispatch the key to the policy but we will no
4409 // longer dispatch a fallback key to the application.
4410 if (fallbackKeyCode != AKEYCODE_UNKNOWN
4411 && (!fallback || fallbackKeyCode != event.getKeyCode())) {
4412#if DEBUG_OUTBOUND_EVENT_DETAILS
4413 if (fallback) {
4414 ALOGD("Unhandled key event: Policy requested to send key %d"
4415 "as a fallback for %d, but on the DOWN it had requested "
4416 "to send %d instead. Fallback canceled.",
4417 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
4418 } else {
4419 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
4420 "but on the DOWN it had requested to send %d. "
4421 "Fallback canceled.",
4422 originalKeyCode, fallbackKeyCode);
4423 }
4424#endif
4425
4426 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4427 "canceling fallback, policy no longer desires it");
4428 options.keyCode = fallbackKeyCode;
4429 synthesizeCancelationEventsForConnectionLocked(connection, options);
4430
4431 fallback = false;
4432 fallbackKeyCode = AKEYCODE_UNKNOWN;
4433 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
4434 connection->inputState.setFallbackKey(originalKeyCode,
4435 fallbackKeyCode);
4436 }
4437 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004438
4439#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004440 {
4441 std::string msg;
4442 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4443 connection->inputState.getFallbackKeys();
4444 for (size_t i = 0; i < fallbackKeys.size(); i++) {
4445 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i),
4446 fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004447 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004448 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
4449 fallbackKeys.size(), msg.c_str());
4450 }
4451#endif
4452
4453 if (fallback) {
4454 // Restart the dispatch cycle using the fallback key.
4455 keyEntry->eventTime = event.getEventTime();
4456 keyEntry->deviceId = event.getDeviceId();
4457 keyEntry->source = event.getSource();
4458 keyEntry->displayId = event.getDisplayId();
4459 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4460 keyEntry->keyCode = fallbackKeyCode;
4461 keyEntry->scanCode = event.getScanCode();
4462 keyEntry->metaState = event.getMetaState();
4463 keyEntry->repeatCount = event.getRepeatCount();
4464 keyEntry->downTime = event.getDownTime();
4465 keyEntry->syntheticRepeat = false;
4466
4467#if DEBUG_OUTBOUND_EVENT_DETAILS
4468 ALOGD("Unhandled key event: Dispatching fallback key. "
4469 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4470 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
4471#endif
4472 return true; // restart the event
4473 } else {
4474#if DEBUG_OUTBOUND_EVENT_DETAILS
4475 ALOGD("Unhandled key event: No fallback key.");
4476#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004477
4478 // Report the key as unhandled, since there is no fallback key.
4479 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004480 }
4481 }
4482 return false;
4483}
4484
4485bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
4486 DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
4487 return false;
4488}
4489
4490void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4491 mLock.unlock();
4492
4493 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4494
4495 mLock.lock();
4496}
4497
4498void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004499 event->initialize(entry->deviceId, entry->source, entry->displayId, entry->action, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004500 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
4501 entry->downTime, entry->eventTime);
4502}
4503
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004504void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry* entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004505 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
4506 // TODO Write some statistics about how long we spend waiting.
4507}
4508
4509void InputDispatcher::traceInboundQueueLengthLocked() {
4510 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004511 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004512 }
4513}
4514
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004515void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004516 if (ATRACE_ENABLED()) {
4517 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004518 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004519 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004520 }
4521}
4522
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004523void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004524 if (ATRACE_ENABLED()) {
4525 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004526 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004527 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004528 }
4529}
4530
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004531void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004532 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004533
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004534 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004535 dumpDispatchStateLocked(dump);
4536
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004537 if (!mLastANRState.empty()) {
4538 dump += "\nInput Dispatcher State at time of last ANR:\n";
4539 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004540 }
4541}
4542
4543void InputDispatcher::monitor() {
4544 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004545 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004546 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004547 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004548}
4549
4550
Michael Wrightd02c5b62014-02-10 15:10:22 -08004551// --- InputDispatcher::InjectionState ---
4552
4553InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
4554 refCount(1),
4555 injectorPid(injectorPid), injectorUid(injectorUid),
4556 injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
4557 pendingForegroundDispatches(0) {
4558}
4559
4560InputDispatcher::InjectionState::~InjectionState() {
4561}
4562
4563void InputDispatcher::InjectionState::release() {
4564 refCount -= 1;
4565 if (refCount == 0) {
4566 delete this;
4567 } else {
4568 ALOG_ASSERT(refCount > 0);
4569 }
4570}
4571
4572
4573// --- InputDispatcher::EventEntry ---
4574
Prabir Pradhan42611e02018-11-27 14:04:02 -08004575InputDispatcher::EventEntry::EventEntry(uint32_t sequenceNum, int32_t type,
4576 nsecs_t eventTime, uint32_t policyFlags) :
4577 sequenceNum(sequenceNum), refCount(1), type(type), eventTime(eventTime),
4578 policyFlags(policyFlags), injectionState(nullptr), dispatchInProgress(false) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004579}
4580
4581InputDispatcher::EventEntry::~EventEntry() {
4582 releaseInjectionState();
4583}
4584
4585void InputDispatcher::EventEntry::release() {
4586 refCount -= 1;
4587 if (refCount == 0) {
4588 delete this;
4589 } else {
4590 ALOG_ASSERT(refCount > 0);
4591 }
4592}
4593
4594void InputDispatcher::EventEntry::releaseInjectionState() {
4595 if (injectionState) {
4596 injectionState->release();
Yi Kong9b14ac62018-07-17 13:48:38 -07004597 injectionState = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004598 }
4599}
4600
4601
4602// --- InputDispatcher::ConfigurationChangedEntry ---
4603
Prabir Pradhan42611e02018-11-27 14:04:02 -08004604InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(
4605 uint32_t sequenceNum, nsecs_t eventTime) :
4606 EventEntry(sequenceNum, TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004607}
4608
4609InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
4610}
4611
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004612void InputDispatcher::ConfigurationChangedEntry::appendDescription(std::string& msg) const {
4613 msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004614}
4615
4616
4617// --- InputDispatcher::DeviceResetEntry ---
4618
Prabir Pradhan42611e02018-11-27 14:04:02 -08004619InputDispatcher::DeviceResetEntry::DeviceResetEntry(
4620 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId) :
4621 EventEntry(sequenceNum, TYPE_DEVICE_RESET, eventTime, 0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004622 deviceId(deviceId) {
4623}
4624
4625InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
4626}
4627
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004628void InputDispatcher::DeviceResetEntry::appendDescription(std::string& msg) const {
4629 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x",
Michael Wrightd02c5b62014-02-10 15:10:22 -08004630 deviceId, policyFlags);
4631}
4632
4633
4634// --- InputDispatcher::KeyEntry ---
4635
Prabir Pradhan42611e02018-11-27 14:04:02 -08004636InputDispatcher::KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004637 int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004638 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
4639 int32_t repeatCount, nsecs_t downTime) :
Prabir Pradhan42611e02018-11-27 14:04:02 -08004640 EventEntry(sequenceNum, TYPE_KEY, eventTime, policyFlags),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004641 deviceId(deviceId), source(source), displayId(displayId), action(action), flags(flags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004642 keyCode(keyCode), scanCode(scanCode), metaState(metaState),
4643 repeatCount(repeatCount), downTime(downTime),
4644 syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
4645 interceptKeyWakeupTime(0) {
4646}
4647
4648InputDispatcher::KeyEntry::~KeyEntry() {
4649}
4650
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004651void InputDispatcher::KeyEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004652 msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004653 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
4654 "repeatCount=%d), policyFlags=0x%08x",
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004655 deviceId, source, displayId, keyActionToString(action).c_str(), flags, keyCode,
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004656 scanCode, metaState, repeatCount, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004657}
4658
4659void InputDispatcher::KeyEntry::recycle() {
4660 releaseInjectionState();
4661
4662 dispatchInProgress = false;
4663 syntheticRepeat = false;
4664 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
4665 interceptKeyWakeupTime = 0;
4666}
4667
4668
4669// --- InputDispatcher::MotionEntry ---
4670
Garfield Tan00f511d2019-06-12 16:55:40 -07004671InputDispatcher::MotionEntry::MotionEntry(
4672 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
4673 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004674 int32_t flags, int32_t metaState, int32_t buttonState, MotionClassification classification,
Garfield Tan00f511d2019-06-12 16:55:40 -07004675 int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition,
4676 float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
Jeff Brownf086ddb2014-02-11 14:28:48 -08004677 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
Garfield Tan00f511d2019-06-12 16:55:40 -07004678 float xOffset, float yOffset)
4679 : EventEntry(sequenceNum, TYPE_MOTION, eventTime, policyFlags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004680 eventTime(eventTime),
Garfield Tan00f511d2019-06-12 16:55:40 -07004681 deviceId(deviceId),
4682 source(source),
4683 displayId(displayId),
4684 action(action),
4685 actionButton(actionButton),
4686 flags(flags),
4687 metaState(metaState),
4688 buttonState(buttonState),
4689 classification(classification),
4690 edgeFlags(edgeFlags),
4691 xPrecision(xPrecision),
4692 yPrecision(yPrecision),
4693 xCursorPosition(xCursorPosition),
4694 yCursorPosition(yCursorPosition),
4695 downTime(downTime),
4696 pointerCount(pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004697 for (uint32_t i = 0; i < pointerCount; i++) {
4698 this->pointerProperties[i].copyFrom(pointerProperties[i]);
4699 this->pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004700 if (xOffset || yOffset) {
4701 this->pointerCoords[i].applyOffset(xOffset, yOffset);
4702 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004703 }
4704}
4705
4706InputDispatcher::MotionEntry::~MotionEntry() {
4707}
4708
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004709void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004710 msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07004711 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
4712 "buttonState=0x%08x, "
4713 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
4714 "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
4715 deviceId, source, displayId, motionActionToString(action).c_str(),
4716 actionButton, flags, metaState, buttonState,
4717 motionClassificationToString(classification), edgeFlags, xPrecision,
4718 yPrecision, xCursorPosition, yCursorPosition);
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004719
Michael Wrightd02c5b62014-02-10 15:10:22 -08004720 for (uint32_t i = 0; i < pointerCount; i++) {
4721 if (i) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004722 msg += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004723 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004724 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004725 pointerCoords[i].getX(), pointerCoords[i].getY());
4726 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004727 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004728}
4729
4730
4731// --- InputDispatcher::DispatchEntry ---
4732
4733volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
4734
4735InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
Robert Carre07e1032018-11-26 12:55:53 -08004736 int32_t targetFlags, float xOffset, float yOffset, float globalScaleFactor,
4737 float windowXScale, float windowYScale) :
Michael Wrightd02c5b62014-02-10 15:10:22 -08004738 seq(nextSeq()),
4739 eventEntry(eventEntry), targetFlags(targetFlags),
Robert Carre07e1032018-11-26 12:55:53 -08004740 xOffset(xOffset), yOffset(yOffset), globalScaleFactor(globalScaleFactor),
4741 windowXScale(windowXScale), windowYScale(windowYScale),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004742 deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
4743 eventEntry->refCount += 1;
4744}
4745
4746InputDispatcher::DispatchEntry::~DispatchEntry() {
4747 eventEntry->release();
4748}
4749
4750uint32_t InputDispatcher::DispatchEntry::nextSeq() {
4751 // Sequence number 0 is reserved and will never be returned.
4752 uint32_t seq;
4753 do {
4754 seq = android_atomic_inc(&sNextSeqAtomic);
4755 } while (!seq);
4756 return seq;
4757}
4758
4759
4760// --- InputDispatcher::InputState ---
4761
4762InputDispatcher::InputState::InputState() {
4763}
4764
4765InputDispatcher::InputState::~InputState() {
4766}
4767
4768bool InputDispatcher::InputState::isNeutral() const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004769 return mKeyMementos.empty() && mMotionMementos.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004770}
4771
4772bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
4773 int32_t displayId) const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004774 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004775 if (memento.deviceId == deviceId
4776 && memento.source == source
4777 && memento.displayId == displayId
4778 && memento.hovering) {
4779 return true;
4780 }
4781 }
4782 return false;
4783}
4784
4785bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
4786 int32_t action, int32_t flags) {
4787 switch (action) {
4788 case AKEY_EVENT_ACTION_UP: {
4789 if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
4790 for (size_t i = 0; i < mFallbackKeys.size(); ) {
4791 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
4792 mFallbackKeys.removeItemsAt(i);
4793 } else {
4794 i += 1;
4795 }
4796 }
4797 }
4798 ssize_t index = findKeyMemento(entry);
4799 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004800 mKeyMementos.erase(mKeyMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004801 return true;
4802 }
4803 /* FIXME: We can't just drop the key up event because that prevents creating
4804 * popup windows that are automatically shown when a key is held and then
4805 * dismissed when the key is released. The problem is that the popup will
4806 * not have received the original key down, so the key up will be considered
4807 * to be inconsistent with its observed state. We could perhaps handle this
4808 * by synthesizing a key down but that will cause other problems.
4809 *
4810 * So for now, allow inconsistent key up events to be dispatched.
4811 *
4812#if DEBUG_OUTBOUND_EVENT_DETAILS
4813 ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
4814 "keyCode=%d, scanCode=%d",
4815 entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
4816#endif
4817 return false;
4818 */
4819 return true;
4820 }
4821
4822 case AKEY_EVENT_ACTION_DOWN: {
4823 ssize_t index = findKeyMemento(entry);
4824 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004825 mKeyMementos.erase(mKeyMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004826 }
4827 addKeyMemento(entry, flags);
4828 return true;
4829 }
4830
4831 default:
4832 return true;
4833 }
4834}
4835
4836bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
4837 int32_t action, int32_t flags) {
4838 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
4839 switch (actionMasked) {
4840 case AMOTION_EVENT_ACTION_UP:
4841 case AMOTION_EVENT_ACTION_CANCEL: {
4842 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4843 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004844 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004845 return true;
4846 }
4847#if DEBUG_OUTBOUND_EVENT_DETAILS
4848 ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004849 "displayId=%" PRId32 ", actionMasked=%d",
4850 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004851#endif
4852 return false;
4853 }
4854
4855 case AMOTION_EVENT_ACTION_DOWN: {
4856 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4857 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004858 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004859 }
4860 addMotionMemento(entry, flags, false /*hovering*/);
4861 return true;
4862 }
4863
4864 case AMOTION_EVENT_ACTION_POINTER_UP:
4865 case AMOTION_EVENT_ACTION_POINTER_DOWN:
4866 case AMOTION_EVENT_ACTION_MOVE: {
Michael Wright38dcdff2014-03-19 12:06:10 -07004867 if (entry->source & AINPUT_SOURCE_CLASS_NAVIGATION) {
4868 // Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need to
4869 // generate cancellation events for these since they're based in relative rather than
4870 // absolute units.
4871 return true;
4872 }
4873
Michael Wrightd02c5b62014-02-10 15:10:22 -08004874 ssize_t index = findMotionMemento(entry, false /*hovering*/);
Michael Wright38dcdff2014-03-19 12:06:10 -07004875
4876 if (entry->source & AINPUT_SOURCE_CLASS_JOYSTICK) {
4877 // Joysticks can send MOVE events without a corresponding DOWN or UP. Since all
4878 // joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral. Any
4879 // other value and we need to track the motion so we can send cancellation events for
4880 // anything generating fallback events (e.g. DPad keys for joystick movements).
4881 if (index >= 0) {
4882 if (entry->pointerCoords[0].isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004883 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wright38dcdff2014-03-19 12:06:10 -07004884 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004885 MotionMemento& memento = mMotionMementos[index];
Michael Wright38dcdff2014-03-19 12:06:10 -07004886 memento.setPointers(entry);
4887 }
4888 } else if (!entry->pointerCoords[0].isEmpty()) {
4889 addMotionMemento(entry, flags, false /*hovering*/);
4890 }
4891
4892 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
4893 return true;
4894 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004895 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004896 MotionMemento& memento = mMotionMementos[index];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004897 memento.setPointers(entry);
4898 return true;
4899 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004900#if DEBUG_OUTBOUND_EVENT_DETAILS
4901 ALOGD("Dropping inconsistent motion pointer up/down or move event: "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004902 "deviceId=%d, source=%08x, displayId=%" PRId32 ", actionMasked=%d",
4903 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004904#endif
4905 return false;
4906 }
4907
4908 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
4909 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4910 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004911 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004912 return true;
4913 }
4914#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004915 ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x, "
4916 "displayId=%" PRId32,
4917 entry->deviceId, entry->source, entry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004918#endif
4919 return false;
4920 }
4921
4922 case AMOTION_EVENT_ACTION_HOVER_ENTER:
4923 case AMOTION_EVENT_ACTION_HOVER_MOVE: {
4924 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4925 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004926 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004927 }
4928 addMotionMemento(entry, flags, true /*hovering*/);
4929 return true;
4930 }
4931
4932 default:
4933 return true;
4934 }
4935}
4936
4937ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
4938 for (size_t i = 0; i < mKeyMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004939 const KeyMemento& memento = mKeyMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004940 if (memento.deviceId == entry->deviceId
4941 && memento.source == entry->source
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004942 && memento.displayId == entry->displayId
Michael Wrightd02c5b62014-02-10 15:10:22 -08004943 && memento.keyCode == entry->keyCode
4944 && memento.scanCode == entry->scanCode) {
4945 return i;
4946 }
4947 }
4948 return -1;
4949}
4950
4951ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
4952 bool hovering) const {
4953 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004954 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004955 if (memento.deviceId == entry->deviceId
4956 && memento.source == entry->source
4957 && memento.displayId == entry->displayId
4958 && memento.hovering == hovering) {
4959 return i;
4960 }
4961 }
4962 return -1;
4963}
4964
4965void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004966 KeyMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004967 memento.deviceId = entry->deviceId;
4968 memento.source = entry->source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004969 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004970 memento.keyCode = entry->keyCode;
4971 memento.scanCode = entry->scanCode;
4972 memento.metaState = entry->metaState;
4973 memento.flags = flags;
4974 memento.downTime = entry->downTime;
4975 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004976 mKeyMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004977}
4978
4979void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
4980 int32_t flags, bool hovering) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004981 MotionMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004982 memento.deviceId = entry->deviceId;
4983 memento.source = entry->source;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004984 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004985 memento.flags = flags;
4986 memento.xPrecision = entry->xPrecision;
4987 memento.yPrecision = entry->yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -07004988 memento.xCursorPosition = entry->xCursorPosition;
4989 memento.yCursorPosition = entry->yCursorPosition;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004990 memento.downTime = entry->downTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004991 memento.setPointers(entry);
4992 memento.hovering = hovering;
4993 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004994 mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004995}
4996
4997void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
4998 pointerCount = entry->pointerCount;
4999 for (uint32_t i = 0; i < entry->pointerCount; i++) {
5000 pointerProperties[i].copyFrom(entry->pointerProperties[i]);
5001 pointerCoords[i].copyFrom(entry->pointerCoords[i]);
5002 }
5003}
5004
5005void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005006 std::vector<EventEntry*>& outEvents, const CancelationOptions& options) {
5007 for (KeyMemento& memento : mKeyMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005008 if (shouldCancelKey(memento, options)) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005009 outEvents.push_back(new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005010 memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08005011 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
5012 memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
5013 }
5014 }
5015
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005016 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005017 if (shouldCancelMotion(memento, options)) {
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08005018 const int32_t action = memento.hovering ?
5019 AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
Garfield Tan00f511d2019-06-12 16:55:40 -07005020 outEvents.push_back(
5021 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, memento.deviceId,
5022 memento.source, memento.displayId, memento.policyFlags, action,
5023 0 /*actionButton*/, memento.flags, AMETA_NONE,
5024 0 /*buttonState*/, MotionClassification::NONE,
5025 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
5026 memento.yPrecision, memento.xCursorPosition,
5027 memento.yCursorPosition, memento.downTime, memento.pointerCount,
5028 memento.pointerProperties, memento.pointerCoords, 0 /*xOffset*/,
5029 0 /*yOffset*/));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005030 }
5031 }
5032}
5033
5034void InputDispatcher::InputState::clear() {
5035 mKeyMementos.clear();
5036 mMotionMementos.clear();
5037 mFallbackKeys.clear();
5038}
5039
5040void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
5041 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005042 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005043 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
5044 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005045 const MotionMemento& otherMemento = other.mMotionMementos[j];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005046 if (memento.deviceId == otherMemento.deviceId
5047 && memento.source == otherMemento.source
5048 && memento.displayId == otherMemento.displayId) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005049 other.mMotionMementos.erase(other.mMotionMementos.begin() + j);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005050 } else {
5051 j += 1;
5052 }
5053 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005054 other.mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005055 }
5056 }
5057}
5058
5059int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
5060 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5061 return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
5062}
5063
5064void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
5065 int32_t fallbackKeyCode) {
5066 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5067 if (index >= 0) {
5068 mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
5069 } else {
5070 mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
5071 }
5072}
5073
5074void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
5075 mFallbackKeys.removeItem(originalKeyCode);
5076}
5077
5078bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
5079 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005080 if (options.keyCode && memento.keyCode != options.keyCode.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005081 return false;
5082 }
5083
Michael Wright3dd60e22019-03-27 22:06:44 +00005084 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5085 return false;
5086 }
5087
5088 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005089 return false;
5090 }
5091
5092 switch (options.mode) {
5093 case CancelationOptions::CANCEL_ALL_EVENTS:
5094 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5095 return true;
5096 case CancelationOptions::CANCEL_FALLBACK_EVENTS:
5097 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
5098 default:
5099 return false;
5100 }
5101}
5102
5103bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
5104 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005105 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5106 return false;
5107 }
5108
5109 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005110 return false;
5111 }
5112
5113 switch (options.mode) {
5114 case CancelationOptions::CANCEL_ALL_EVENTS:
5115 return true;
5116 case CancelationOptions::CANCEL_POINTER_EVENTS:
5117 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
5118 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5119 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
5120 default:
5121 return false;
5122 }
5123}
5124
5125
5126// --- InputDispatcher::Connection ---
5127
Robert Carr803535b2018-08-02 16:38:15 -07005128InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel, bool monitor) :
5129 status(STATUS_NORMAL), inputChannel(inputChannel),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005130 monitor(monitor),
5131 inputPublisher(inputChannel), inputPublisherBlocked(false) {
5132}
5133
5134InputDispatcher::Connection::~Connection() {
5135}
5136
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005137const std::string InputDispatcher::Connection::getWindowName() const {
Robert Carr803535b2018-08-02 16:38:15 -07005138 if (inputChannel != nullptr) {
5139 return inputChannel->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005140 }
5141 if (monitor) {
5142 return "monitor";
5143 }
5144 return "?";
5145}
5146
5147const char* InputDispatcher::Connection::getStatusLabel() const {
5148 switch (status) {
5149 case STATUS_NORMAL:
5150 return "NORMAL";
5151
5152 case STATUS_BROKEN:
5153 return "BROKEN";
5154
5155 case STATUS_ZOMBIE:
5156 return "ZOMBIE";
5157
5158 default:
5159 return "UNKNOWN";
5160 }
5161}
5162
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005163std::deque<InputDispatcher::DispatchEntry*>::iterator
5164InputDispatcher::Connection::findWaitQueueEntry(uint32_t seq) {
5165 for (std::deque<DispatchEntry*>::iterator it = waitQueue.begin(); it != waitQueue.end(); it++) {
5166 if ((*it)->seq == seq) {
5167 return it;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005168 }
5169 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005170 return waitQueue.end();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005171}
5172
Michael Wright3dd60e22019-03-27 22:06:44 +00005173// --- InputDispatcher::Monitor
5174InputDispatcher::Monitor::Monitor(const sp<InputChannel>& inputChannel) :
5175 inputChannel(inputChannel) {
5176}
5177
Michael Wrightd02c5b62014-02-10 15:10:22 -08005178
5179// --- InputDispatcher::CommandEntry ---
Michael Wright3dd60e22019-03-27 22:06:44 +00005180//
Michael Wrightd02c5b62014-02-10 15:10:22 -08005181InputDispatcher::CommandEntry::CommandEntry(Command command) :
Yi Kong9b14ac62018-07-17 13:48:38 -07005182 command(command), eventTime(0), keyEntry(nullptr), userActivityEventType(0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005183 seq(0), handled(false) {
5184}
5185
5186InputDispatcher::CommandEntry::~CommandEntry() {
5187}
5188
Michael Wright3dd60e22019-03-27 22:06:44 +00005189// --- InputDispatcher::TouchedMonitor ---
5190InputDispatcher::TouchedMonitor::TouchedMonitor(const Monitor& monitor, float xOffset,
5191 float yOffset) : monitor(monitor), xOffset(xOffset), yOffset(yOffset) {
5192}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005193
5194// --- InputDispatcher::TouchState ---
5195
5196InputDispatcher::TouchState::TouchState() :
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005197 down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005198}
5199
5200InputDispatcher::TouchState::~TouchState() {
5201}
5202
5203void InputDispatcher::TouchState::reset() {
5204 down = false;
5205 split = false;
5206 deviceId = -1;
5207 source = 0;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005208 displayId = ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005209 windows.clear();
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005210 portalWindows.clear();
Michael Wright3dd60e22019-03-27 22:06:44 +00005211 gestureMonitors.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005212}
5213
5214void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
5215 down = other.down;
5216 split = other.split;
5217 deviceId = other.deviceId;
5218 source = other.source;
5219 displayId = other.displayId;
5220 windows = other.windows;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005221 portalWindows = other.portalWindows;
Michael Wright3dd60e22019-03-27 22:06:44 +00005222 gestureMonitors = other.gestureMonitors;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005223}
5224
5225void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
5226 int32_t targetFlags, BitSet32 pointerIds) {
5227 if (targetFlags & InputTarget::FLAG_SPLIT) {
5228 split = true;
5229 }
5230
5231 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005232 TouchedWindow& touchedWindow = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005233 if (touchedWindow.windowHandle == windowHandle) {
5234 touchedWindow.targetFlags |= targetFlags;
5235 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
5236 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
5237 }
5238 touchedWindow.pointerIds.value |= pointerIds.value;
5239 return;
5240 }
5241 }
5242
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005243 TouchedWindow touchedWindow;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005244 touchedWindow.windowHandle = windowHandle;
5245 touchedWindow.targetFlags = targetFlags;
5246 touchedWindow.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005247 windows.push_back(touchedWindow);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005248}
5249
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005250void InputDispatcher::TouchState::addPortalWindow(const sp<InputWindowHandle>& windowHandle) {
5251 size_t numWindows = portalWindows.size();
5252 for (size_t i = 0; i < numWindows; i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005253 if (portalWindows[i] == windowHandle) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005254 return;
5255 }
5256 }
5257 portalWindows.push_back(windowHandle);
5258}
5259
Michael Wright3dd60e22019-03-27 22:06:44 +00005260void InputDispatcher::TouchState::addGestureMonitors(
5261 const std::vector<TouchedMonitor>& newMonitors) {
5262 const size_t newSize = gestureMonitors.size() + newMonitors.size();
5263 gestureMonitors.reserve(newSize);
5264 gestureMonitors.insert(std::end(gestureMonitors),
5265 std::begin(newMonitors), std::end(newMonitors));
5266}
5267
Michael Wrightd02c5b62014-02-10 15:10:22 -08005268void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
5269 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005270 if (windows[i].windowHandle == windowHandle) {
5271 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005272 return;
5273 }
5274 }
5275}
5276
Robert Carr803535b2018-08-02 16:38:15 -07005277void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) {
5278 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005279 if (windows[i].windowHandle->getToken() == token) {
5280 windows.erase(windows.begin() + i);
Robert Carr803535b2018-08-02 16:38:15 -07005281 return;
5282 }
5283 }
5284}
5285
Michael Wrightd02c5b62014-02-10 15:10:22 -08005286void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
5287 for (size_t i = 0 ; i < windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005288 TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005289 if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
5290 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
5291 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
5292 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
5293 i += 1;
5294 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005295 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005296 }
5297 }
5298}
5299
Michael Wright3dd60e22019-03-27 22:06:44 +00005300void InputDispatcher::TouchState::filterNonMonitors() {
5301 windows.clear();
5302 portalWindows.clear();
5303}
5304
Michael Wrightd02c5b62014-02-10 15:10:22 -08005305sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
5306 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005307 const TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005308 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5309 return window.windowHandle;
5310 }
5311 }
Yi Kong9b14ac62018-07-17 13:48:38 -07005312 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005313}
5314
5315bool InputDispatcher::TouchState::isSlippery() const {
5316 // Must have exactly one foreground window.
5317 bool haveSlipperyForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005318 for (const TouchedWindow& window : windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005319 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5320 if (haveSlipperyForegroundWindow
5321 || !(window.windowHandle->getInfo()->layoutParamsFlags
5322 & InputWindowInfo::FLAG_SLIPPERY)) {
5323 return false;
5324 }
5325 haveSlipperyForegroundWindow = true;
5326 }
5327 }
5328 return haveSlipperyForegroundWindow;
5329}
5330
5331
5332// --- InputDispatcherThread ---
5333
5334InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
5335 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
5336}
5337
5338InputDispatcherThread::~InputDispatcherThread() {
5339}
5340
5341bool InputDispatcherThread::threadLoop() {
5342 mDispatcher->dispatchOnce();
5343 return true;
5344}
5345
5346} // namespace android