blob: f2b95e7f7a32e27002b09d664115531a1ae537ce [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
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
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.
Siarhei Vishniakou86587282019-09-09 18:20:15 +010038static constexpr bool DEBUG_FOCUS = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -080039
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
Garfield Tane84e6f92019-08-29 17:28:41 -070048#include "Connection.h"
49
Michael Wrightd02c5b62014-02-10 15:10:22 -080050#include <errno.h>
Siarhei Vishniakou443ad902019-03-06 17:25:41 -080051#include <inttypes.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080052#include <limits.h>
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -050053#include <statslog.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070054#include <stddef.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080055#include <time.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070056#include <unistd.h>
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -070057#include <queue>
58#include <sstream>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070059
Michael Wright2b3c3302018-03-02 17:19:13 +000060#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080061#include <android-base/stringprintf.h>
Robert Carr4e670e52018-08-15 13:26:12 -070062#include <binder/Binder.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070063#include <log/log.h>
64#include <powermanager/PowerManager.h>
65#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080066
67#define INDENT " "
68#define INDENT2 " "
69#define INDENT3 " "
70#define INDENT4 " "
71
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080072using android::base::StringPrintf;
73
Garfield Tane84e6f92019-08-29 17:28:41 -070074namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080075
76// Default input dispatching timeout if there is no focused application or paused window
77// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000078constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080079
80// Amount of time to allow for all pending events to be processed when an app switch
81// key is on the way. This is used to preempt input dispatch and drop input events
82// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000083constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080084
85// Amount of time to allow for an event to be dispatched (measured since its eventTime)
86// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000087constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080088
89// Amount of time to allow touch events to be streamed out to a connection before requiring
90// that the first event be finished. This value extends the ANR timeout by the specified
91// amount. For example, if streaming is allowed to get ahead by one second relative to the
92// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000093constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080094
95// 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 +000096constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
97
98// Log a warning when an interception call takes longer than this to process.
99constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800100
101// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000102constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
103
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104static inline nsecs_t now() {
105 return systemTime(SYSTEM_TIME_MONOTONIC);
106}
107
108static inline const char* toString(bool value) {
109 return value ? "true" : "false";
110}
111
112static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700113 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
114 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115}
116
117static bool isValidKeyAction(int32_t action) {
118 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700119 case AKEY_EVENT_ACTION_DOWN:
120 case AKEY_EVENT_ACTION_UP:
121 return true;
122 default:
123 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800124 }
125}
126
127static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700128 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800129 ALOGE("Key event has invalid action code 0x%x", action);
130 return false;
131 }
132 return true;
133}
134
Michael Wright7b159c92015-05-14 14:48:03 +0100135static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800136 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700137 case AMOTION_EVENT_ACTION_DOWN:
138 case AMOTION_EVENT_ACTION_UP:
139 case AMOTION_EVENT_ACTION_CANCEL:
140 case AMOTION_EVENT_ACTION_MOVE:
141 case AMOTION_EVENT_ACTION_OUTSIDE:
142 case AMOTION_EVENT_ACTION_HOVER_ENTER:
143 case AMOTION_EVENT_ACTION_HOVER_MOVE:
144 case AMOTION_EVENT_ACTION_HOVER_EXIT:
145 case AMOTION_EVENT_ACTION_SCROLL:
146 return true;
147 case AMOTION_EVENT_ACTION_POINTER_DOWN:
148 case AMOTION_EVENT_ACTION_POINTER_UP: {
149 int32_t index = getMotionEventActionPointerIndex(action);
150 return index >= 0 && index < pointerCount;
151 }
152 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
153 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
154 return actionButton != 0;
155 default:
156 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800157 }
158}
159
Michael Wright7b159c92015-05-14 14:48:03 +0100160static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700161 const PointerProperties* pointerProperties) {
162 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800163 ALOGE("Motion event has invalid action code 0x%x", action);
164 return false;
165 }
166 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000167 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700168 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800169 return false;
170 }
171 BitSet32 pointerIdBits;
172 for (size_t i = 0; i < pointerCount; i++) {
173 int32_t id = pointerProperties[i].id;
174 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700175 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
176 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800177 return false;
178 }
179 if (pointerIdBits.hasBit(id)) {
180 ALOGE("Motion event has duplicate pointer id %d", id);
181 return false;
182 }
183 pointerIdBits.markBit(id);
184 }
185 return true;
186}
187
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800188static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800189 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800190 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800191 return;
192 }
193
194 bool first = true;
195 Region::const_iterator cur = region.begin();
196 Region::const_iterator const tail = region.end();
197 while (cur != tail) {
198 if (first) {
199 first = false;
200 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800201 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800202 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800203 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 cur++;
205 }
206}
207
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700208/**
209 * Find the entry in std::unordered_map by key, and return it.
210 * If the entry is not found, return a default constructed entry.
211 *
212 * Useful when the entries are vectors, since an empty vector will be returned
213 * if the entry is not found.
214 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
215 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700216template <typename K, typename V>
217static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700218 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700219 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800220}
221
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700222/**
223 * Find the entry in std::unordered_map by value, and remove it.
224 * If more than one entry has the same value, then all matching
225 * key-value pairs will be removed.
226 *
227 * Return true if at least one value has been removed.
228 */
229template <typename K, typename V>
230static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
231 bool removed = false;
232 for (auto it = map.begin(); it != map.end();) {
233 if (it->second == value) {
234 it = map.erase(it);
235 removed = true;
236 } else {
237 it++;
238 }
239 }
240 return removed;
241}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800242
chaviwaf87b3e2019-10-01 16:59:28 -0700243static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
244 if (first == second) {
245 return true;
246 }
247
248 if (first == nullptr || second == nullptr) {
249 return false;
250 }
251
252 return first->getToken() == second->getToken();
253}
254
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800255static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
256 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
257}
258
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000259static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
260 EventEntry* eventEntry,
261 int32_t inputTargetFlags) {
262 if (inputTarget.useDefaultPointerInfo()) {
263 const PointerInfo& pointerInfo = inputTarget.getDefaultPointerInfo();
264 return std::make_unique<DispatchEntry>(eventEntry, // increments ref
265 inputTargetFlags, pointerInfo.xOffset,
266 pointerInfo.yOffset, inputTarget.globalScaleFactor,
267 pointerInfo.windowXScale, pointerInfo.windowYScale);
268 }
269
270 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
271 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
272
273 PointerCoords pointerCoords[motionEntry.pointerCount];
274
275 // Use the first pointer information to normalize all other pointers. This could be any pointer
276 // as long as all other pointers are normalized to the same value and the final DispatchEntry
277 // uses the offset and scale for the normalized pointer.
278 const PointerInfo& firstPointerInfo =
279 inputTarget.pointerInfos[inputTarget.pointerIds.firstMarkedBit()];
280
281 // Iterate through all pointers in the event to normalize against the first.
282 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
283 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
284 uint32_t pointerId = uint32_t(pointerProperties.id);
285 const PointerInfo& currPointerInfo = inputTarget.pointerInfos[pointerId];
286
287 // The scale factor is the ratio of the current pointers scale to the normalized scale.
288 float scaleXDiff = currPointerInfo.windowXScale / firstPointerInfo.windowXScale;
289 float scaleYDiff = currPointerInfo.windowYScale / firstPointerInfo.windowYScale;
290
291 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
292 // First apply the current pointers offset to set the window at 0,0
293 pointerCoords[pointerIndex].applyOffset(currPointerInfo.xOffset, currPointerInfo.yOffset);
294 // Next scale the coordinates.
295 pointerCoords[pointerIndex].scale(1, scaleXDiff, scaleYDiff);
296 // Lastly, offset the coordinates so they're in the normalized pointer's frame.
297 pointerCoords[pointerIndex].applyOffset(-firstPointerInfo.xOffset,
298 -firstPointerInfo.yOffset);
299 }
300
301 MotionEntry* combinedMotionEntry =
302 new MotionEntry(motionEntry.sequenceNum, motionEntry.eventTime, motionEntry.deviceId,
303 motionEntry.source, motionEntry.displayId, motionEntry.policyFlags,
304 motionEntry.action, motionEntry.actionButton, motionEntry.flags,
305 motionEntry.metaState, motionEntry.buttonState,
306 motionEntry.classification, motionEntry.edgeFlags,
307 motionEntry.xPrecision, motionEntry.yPrecision,
308 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
309 motionEntry.downTime, motionEntry.pointerCount,
310 motionEntry.pointerProperties, pointerCoords, 0 /* xOffset */,
311 0 /* yOffset */);
312
313 if (motionEntry.injectionState) {
314 combinedMotionEntry->injectionState = motionEntry.injectionState;
315 combinedMotionEntry->injectionState->refCount += 1;
316 }
317
318 std::unique_ptr<DispatchEntry> dispatchEntry =
319 std::make_unique<DispatchEntry>(combinedMotionEntry, // increments ref
320 inputTargetFlags, firstPointerInfo.xOffset,
321 firstPointerInfo.yOffset, inputTarget.globalScaleFactor,
322 firstPointerInfo.windowXScale,
323 firstPointerInfo.windowYScale);
324 combinedMotionEntry->release();
325 return dispatchEntry;
326}
327
Michael Wrightd02c5b62014-02-10 15:10:22 -0800328// --- InputDispatcher ---
329
Garfield Tan00f511d2019-06-12 16:55:40 -0700330InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
331 : mPolicy(policy),
332 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700333 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tan00f511d2019-06-12 16:55:40 -0700334 mAppSwitchSawKeyDown(false),
335 mAppSwitchDueTime(LONG_LONG_MAX),
336 mNextUnblockedEvent(nullptr),
337 mDispatchEnabled(false),
338 mDispatchFrozen(false),
339 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800340 // mInTouchMode will be initialized by the WindowManager to the default device config.
341 // To avoid leaking stack in case that call never comes, and for tests,
342 // initialize it here anyways.
343 mInTouchMode(true),
Garfield Tan00f511d2019-06-12 16:55:40 -0700344 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
345 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800346 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800347 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800348
Yi Kong9b14ac62018-07-17 13:48:38 -0700349 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800350
351 policy->getDispatcherConfiguration(&mConfig);
352}
353
354InputDispatcher::~InputDispatcher() {
355 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800356 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800357
358 resetKeyRepeatLocked();
359 releasePendingEventLocked();
360 drainInboundQueueLocked();
361 }
362
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700363 while (!mConnectionsByFd.empty()) {
364 sp<Connection> connection = mConnectionsByFd.begin()->second;
365 unregisterInputChannel(connection->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800366 }
367}
368
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700369status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700370 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700371 return ALREADY_EXISTS;
372 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700373 mThread = std::make_unique<InputThread>(
374 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
375 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700376}
377
378status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700379 if (mThread && mThread->isCallingThread()) {
380 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700381 return INVALID_OPERATION;
382 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700383 mThread.reset();
384 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700385}
386
Michael Wrightd02c5b62014-02-10 15:10:22 -0800387void InputDispatcher::dispatchOnce() {
388 nsecs_t nextWakeupTime = LONG_LONG_MAX;
389 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800390 std::scoped_lock _l(mLock);
391 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800392
393 // Run a dispatch loop if there are no pending commands.
394 // The dispatch loop might enqueue commands to run afterwards.
395 if (!haveCommandsLocked()) {
396 dispatchOnceInnerLocked(&nextWakeupTime);
397 }
398
399 // Run all pending commands if there are any.
400 // If any commands were run then force the next poll to wake up immediately.
401 if (runCommandsLockedInterruptible()) {
402 nextWakeupTime = LONG_LONG_MIN;
403 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800404
405 // We are about to enter an infinitely long sleep, because we have no commands or
406 // pending or queued events
407 if (nextWakeupTime == LONG_LONG_MAX) {
408 mDispatcherEnteredIdle.notify_all();
409 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800410 } // release lock
411
412 // Wait for callback or timeout or wake. (make sure we round up, not down)
413 nsecs_t currentTime = now();
414 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
415 mLooper->pollOnce(timeoutMillis);
416}
417
418void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
419 nsecs_t currentTime = now();
420
Jeff Browndc5992e2014-04-11 01:27:26 -0700421 // Reset the key repeat timer whenever normal dispatch is suspended while the
422 // device is in a non-interactive state. This is to ensure that we abort a key
423 // repeat if the device is just coming out of sleep.
424 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800425 resetKeyRepeatLocked();
426 }
427
428 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
429 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100430 if (DEBUG_FOCUS) {
431 ALOGD("Dispatch frozen. Waiting some more.");
432 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800433 return;
434 }
435
436 // Optimize latency of app switches.
437 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
438 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
439 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
440 if (mAppSwitchDueTime < *nextWakeupTime) {
441 *nextWakeupTime = mAppSwitchDueTime;
442 }
443
444 // Ready to start a new event.
445 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700446 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700447 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800448 if (isAppSwitchDue) {
449 // The inbound queue is empty so the app switch key we were waiting
450 // for will never arrive. Stop waiting for it.
451 resetPendingAppSwitchLocked(false);
452 isAppSwitchDue = false;
453 }
454
455 // Synthesize a key repeat if appropriate.
456 if (mKeyRepeatState.lastKeyEntry) {
457 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
458 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
459 } else {
460 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
461 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
462 }
463 }
464 }
465
466 // Nothing to do if there is no pending event.
467 if (!mPendingEvent) {
468 return;
469 }
470 } else {
471 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700472 mPendingEvent = mInboundQueue.front();
473 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800474 traceInboundQueueLengthLocked();
475 }
476
477 // Poke user activity for this event.
478 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700479 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800480 }
481
482 // Get ready to dispatch the event.
483 resetANRTimeoutsLocked();
484 }
485
486 // Now we have an event to dispatch.
487 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700488 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800489 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700490 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800491 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700492 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800493 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700494 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800495 }
496
497 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700498 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800499 }
500
501 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700502 case EventEntry::Type::CONFIGURATION_CHANGED: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700503 ConfigurationChangedEntry* typedEntry =
504 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
505 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700506 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700507 break;
508 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800509
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700510 case EventEntry::Type::DEVICE_RESET: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700511 DeviceResetEntry* typedEntry = static_cast<DeviceResetEntry*>(mPendingEvent);
512 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700513 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700514 break;
515 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800516
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100517 case EventEntry::Type::FOCUS: {
518 FocusEntry* typedEntry = static_cast<FocusEntry*>(mPendingEvent);
519 dispatchFocusLocked(currentTime, typedEntry);
520 done = true;
521 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
522 break;
523 }
524
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700525 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700526 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
527 if (isAppSwitchDue) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700528 if (isAppSwitchKeyEvent(*typedEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700529 resetPendingAppSwitchLocked(true);
530 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700531 } else if (dropReason == DropReason::NOT_DROPPED) {
532 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700533 }
534 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700535 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700536 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700537 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700538 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
539 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700540 }
541 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
542 break;
543 }
544
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700545 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700546 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700547 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
548 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800549 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700550 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700551 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700552 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700553 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
554 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700555 }
556 done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
557 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800558 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800559 }
560
561 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700562 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700563 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800564 }
Michael Wright3a981722015-06-10 15:26:13 +0100565 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800566
567 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700568 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800569 }
570}
571
572bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700573 bool needWake = mInboundQueue.empty();
574 mInboundQueue.push_back(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800575 traceInboundQueueLengthLocked();
576
577 switch (entry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700578 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700579 // Optimize app switch latency.
580 // If the application takes too long to catch up then we drop all events preceding
581 // the app switch key.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700582 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700583 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700584 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700585 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700586 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700587 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800588#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700589 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800590#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700591 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700592 mAppSwitchSawKeyDown = false;
593 needWake = true;
594 }
595 }
596 }
597 break;
598 }
599
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700600 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700601 // Optimize case where the current application is unresponsive and the user
602 // decides to touch a window in a different application.
603 // If the application takes too long to catch up then we drop all events preceding
604 // the touch into the other window.
605 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
606 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN &&
607 (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
608 mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY &&
609 mInputTargetWaitApplicationToken != nullptr) {
610 int32_t displayId = motionEntry->displayId;
611 int32_t x =
612 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
613 int32_t y =
614 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
615 sp<InputWindowHandle> touchedWindowHandle =
616 findTouchedWindowAtLocked(displayId, x, y);
617 if (touchedWindowHandle != nullptr &&
618 touchedWindowHandle->getApplicationToken() !=
619 mInputTargetWaitApplicationToken) {
620 // User touched a different application than the one we are waiting on.
621 // Flag the event, and start pruning the input queue.
622 mNextUnblockedEvent = motionEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800623 needWake = true;
624 }
625 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700626 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800627 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700628 case EventEntry::Type::CONFIGURATION_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100629 case EventEntry::Type::DEVICE_RESET:
630 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700631 // nothing to do
632 break;
633 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800634 }
635
636 return needWake;
637}
638
639void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
640 entry->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700641 mRecentQueue.push_back(entry);
642 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
643 mRecentQueue.front()->release();
644 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800645 }
646}
647
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700648sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
649 int32_t y, bool addOutsideTargets,
650 bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800651 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800652 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
653 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800654 const InputWindowInfo* windowInfo = windowHandle->getInfo();
655 if (windowInfo->displayId == displayId) {
656 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800657
658 if (windowInfo->visible) {
659 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700660 bool isTouchModal = (flags &
661 (InputWindowInfo::FLAG_NOT_FOCUSABLE |
662 InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800663 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800664 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700665 if (portalToDisplayId != ADISPLAY_ID_NONE &&
666 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800667 if (addPortalWindows) {
668 // For the monitoring channels of the display.
669 mTempTouchState.addPortalWindow(windowHandle);
670 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700671 return findTouchedWindowAtLocked(portalToDisplayId, x, y,
672 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800673 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800674 // Found window.
675 return windowHandle;
676 }
677 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800678
679 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700680 mTempTouchState.addOrUpdateWindow(windowHandle,
681 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
682 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800683 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800684 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800685 }
686 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700687 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800688}
689
Garfield Tane84e6f92019-08-29 17:28:41 -0700690std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +0000691 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
692 std::vector<TouchedMonitor> touchedMonitors;
693
694 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
695 addGestureMonitors(monitors, touchedMonitors);
696 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
697 const InputWindowInfo* windowInfo = portalWindow->getInfo();
698 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700699 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
700 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000701 }
702 return touchedMonitors;
703}
704
705void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700706 std::vector<TouchedMonitor>& outTouchedMonitors,
707 float xOffset, float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000708 if (monitors.empty()) {
709 return;
710 }
711 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
712 for (const Monitor& monitor : monitors) {
713 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
714 }
715}
716
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700717void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800718 const char* reason;
719 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700720 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800721#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700722 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800723#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700724 reason = "inbound event was dropped because the policy consumed it";
725 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700726 case DropReason::DISABLED:
727 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700728 ALOGI("Dropped event because input dispatch is disabled.");
729 }
730 reason = "inbound event was dropped because input dispatch is disabled";
731 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700732 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700733 ALOGI("Dropped event because of pending overdue app switch.");
734 reason = "inbound event was dropped because of pending overdue app switch";
735 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700736 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700737 ALOGI("Dropped event because the current application is not responding and the user "
738 "has started interacting with a different application.");
739 reason = "inbound event was dropped because the current application is not responding "
740 "and the user has started interacting with a different application";
741 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700742 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700743 ALOGI("Dropped event because it is stale.");
744 reason = "inbound event was dropped because it is stale";
745 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700746 case DropReason::NOT_DROPPED: {
747 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700748 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700749 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800750 }
751
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700752 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700753 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800754 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
755 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700756 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800757 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700758 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700759 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
760 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700761 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
762 synthesizeCancelationEventsForAllConnectionsLocked(options);
763 } else {
764 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
765 synthesizeCancelationEventsForAllConnectionsLocked(options);
766 }
767 break;
768 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100769 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700770 case EventEntry::Type::CONFIGURATION_CHANGED:
771 case EventEntry::Type::DEVICE_RESET: {
772 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
773 break;
774 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800775 }
776}
777
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800778static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700779 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
780 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800781}
782
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700783bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
784 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
785 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
786 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800787}
788
789bool InputDispatcher::isAppSwitchPendingLocked() {
790 return mAppSwitchDueTime != LONG_LONG_MAX;
791}
792
793void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
794 mAppSwitchDueTime = LONG_LONG_MAX;
795
796#if DEBUG_APP_SWITCH
797 if (handled) {
798 ALOGD("App switch has arrived.");
799 } else {
800 ALOGD("App switch was abandoned.");
801 }
802#endif
803}
804
Michael Wrightd02c5b62014-02-10 15:10:22 -0800805bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700806 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800807}
808
809bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700810 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800811 return false;
812 }
813
814 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700815 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700816 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800817 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700818 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800819
820 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700821 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800822 return true;
823}
824
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700825void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
826 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800827}
828
829void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700830 while (!mInboundQueue.empty()) {
831 EventEntry* entry = mInboundQueue.front();
832 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800833 releaseInboundEventLocked(entry);
834 }
835 traceInboundQueueLengthLocked();
836}
837
838void InputDispatcher::releasePendingEventLocked() {
839 if (mPendingEvent) {
840 resetANRTimeoutsLocked();
841 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700842 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800843 }
844}
845
846void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
847 InjectionState* injectionState = entry->injectionState;
848 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
849#if DEBUG_DISPATCH_CYCLE
850 ALOGD("Injected inbound event was dropped.");
851#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800852 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800853 }
854 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700855 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800856 }
857 addRecentEventLocked(entry);
858 entry->release();
859}
860
861void InputDispatcher::resetKeyRepeatLocked() {
862 if (mKeyRepeatState.lastKeyEntry) {
863 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700864 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800865 }
866}
867
Garfield Tane84e6f92019-08-29 17:28:41 -0700868KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800869 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
870
871 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700872 uint32_t policyFlags = entry->policyFlags &
873 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800874 if (entry->refCount == 1) {
875 entry->recycle();
876 entry->eventTime = currentTime;
877 entry->policyFlags = policyFlags;
878 entry->repeatCount += 1;
879 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700880 KeyEntry* newEntry =
881 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, entry->deviceId,
882 entry->source, entry->displayId, policyFlags, entry->action,
883 entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
884 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800885
886 mKeyRepeatState.lastKeyEntry = newEntry;
887 entry->release();
888
889 entry = newEntry;
890 }
891 entry->syntheticRepeat = true;
892
893 // Increment reference count since we keep a reference to the event in
894 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
895 entry->refCount += 1;
896
897 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
898 return entry;
899}
900
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700901bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
902 ConfigurationChangedEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800903#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700904 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800905#endif
906
907 // Reset key repeating in case a keyboard device was added or removed or something.
908 resetKeyRepeatLocked();
909
910 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700911 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
912 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800913 commandEntry->eventTime = entry->eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700914 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800915 return true;
916}
917
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700918bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceResetEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800919#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700920 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700921 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800922#endif
923
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700924 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800925 options.deviceId = entry->deviceId;
926 synthesizeCancelationEventsForAllConnectionsLocked(options);
927 return true;
928}
929
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100930void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) {
931 FocusEntry* focusEntry =
932 new FocusEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, now(), window.getToken(), hasFocus);
933 enqueueInboundEventLocked(focusEntry);
934}
935
936void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) {
937 sp<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
938 if (channel == nullptr) {
939 return; // Window has gone away
940 }
941 InputTarget target;
942 target.inputChannel = channel;
943 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
944 entry->dispatchInProgress = true;
945
946 dispatchEventLocked(currentTime, entry, {target});
947}
948
Michael Wrightd02c5b62014-02-10 15:10:22 -0800949bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700950 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800951 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700952 if (!entry->dispatchInProgress) {
953 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
954 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
955 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
956 if (mKeyRepeatState.lastKeyEntry &&
957 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800958 // We have seen two identical key downs in a row which indicates that the device
959 // driver is automatically generating key repeats itself. We take note of the
960 // repeat here, but we disable our own next key repeat timer since it is clear that
961 // we will not need to synthesize key repeats ourselves.
962 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
963 resetKeyRepeatLocked();
964 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
965 } else {
966 // Not a repeat. Save key down state in case we do see a repeat later.
967 resetKeyRepeatLocked();
968 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
969 }
970 mKeyRepeatState.lastKeyEntry = entry;
971 entry->refCount += 1;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700972 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800973 resetKeyRepeatLocked();
974 }
975
976 if (entry->repeatCount == 1) {
977 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
978 } else {
979 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
980 }
981
982 entry->dispatchInProgress = true;
983
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700984 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985 }
986
987 // Handle case where the policy asked us to try again later last time.
988 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
989 if (currentTime < entry->interceptKeyWakeupTime) {
990 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
991 *nextWakeupTime = entry->interceptKeyWakeupTime;
992 }
993 return false; // wait until next wakeup
994 }
995 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
996 entry->interceptKeyWakeupTime = 0;
997 }
998
999 // Give the policy a chance to intercept the key.
1000 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1001 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001002 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001003 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +08001004 sp<InputWindowHandle> focusedWindowHandle =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001005 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(*entry));
Tiger Huang721e26f2018-07-24 22:26:19 +08001006 if (focusedWindowHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001007 commandEntry->inputChannel = getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001008 }
1009 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001010 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001011 entry->refCount += 1;
1012 return false; // wait for the command to run
1013 } else {
1014 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1015 }
1016 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001017 if (*dropReason == DropReason::NOT_DROPPED) {
1018 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001019 }
1020 }
1021
1022 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001023 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001024 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001025 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001026 : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08001027 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001028 return true;
1029 }
1030
1031 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001032 std::vector<InputTarget> inputTargets;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001033 int32_t injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001034 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001035 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1036 return false;
1037 }
1038
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001039 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001040 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
1041 return true;
1042 }
1043
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001044 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001045 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001046
1047 // Dispatch the key.
1048 dispatchEventLocked(currentTime, entry, inputTargets);
1049 return true;
1050}
1051
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001052void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001053#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001054 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001055 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1056 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001057 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1058 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1059 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001060#endif
1061}
1062
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001063bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry,
1064 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001065 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001066 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001067 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001068 entry->dispatchInProgress = true;
1069
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001070 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001071 }
1072
1073 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001074 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001075 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001076 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001077 : INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001078 return true;
1079 }
1080
1081 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1082
1083 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001084 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001085
1086 bool conflictingPointerActions = false;
1087 int32_t injectionResult;
1088 if (isPointerEvent) {
1089 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001090 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001091 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001092 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001093 } else {
1094 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001095 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001096 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001097 }
1098 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1099 return false;
1100 }
1101
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001102 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001103 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001104 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001105 CancelationOptions::Mode mode(isPointerEvent
1106 ? CancelationOptions::CANCEL_POINTER_EVENTS
1107 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001108 CancelationOptions options(mode, "input event injection failed");
1109 synthesizeCancelationEventsForMonitorsLocked(options);
1110 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001111 return true;
1112 }
1113
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001114 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001115 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001116
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001117 if (isPointerEvent) {
1118 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1119 if (stateIndex >= 0) {
1120 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001121 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001122 // The event has gone through these portal windows, so we add monitoring targets of
1123 // the corresponding displays as well.
1124 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001125 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001126 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001127 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001128 }
1129 }
1130 }
1131 }
1132
Michael Wrightd02c5b62014-02-10 15:10:22 -08001133 // Dispatch the motion.
1134 if (conflictingPointerActions) {
1135 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001136 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001137 synthesizeCancelationEventsForAllConnectionsLocked(options);
1138 }
1139 dispatchEventLocked(currentTime, entry, inputTargets);
1140 return true;
1141}
1142
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001143void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001144#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001145 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001146 ", policyFlags=0x%x, "
1147 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1148 "metaState=0x%x, buttonState=0x%x,"
1149 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001150 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1151 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1152 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001153
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001154 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001155 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001156 "x=%f, y=%f, pressure=%f, size=%f, "
1157 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1158 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001159 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1160 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1161 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1162 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1163 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1164 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1165 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1166 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1167 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1168 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001169 }
1170#endif
1171}
1172
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001173void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* eventEntry,
1174 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001175 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001176#if DEBUG_DISPATCH_CYCLE
1177 ALOGD("dispatchEventToCurrentInputTargets");
1178#endif
1179
1180 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1181
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001182 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001183
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001184 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001185 sp<Connection> connection =
1186 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001187 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001188 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001189 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001190 if (DEBUG_FOCUS) {
1191 ALOGD("Dropping event delivery to target with channel '%s' because it "
1192 "is no longer registered with the input dispatcher.",
1193 inputTarget.inputChannel->getName().c_str());
1194 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001195 }
1196 }
1197}
1198
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001199int32_t InputDispatcher::handleTargetsNotReadyLocked(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001200 nsecs_t currentTime, const EventEntry& entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001201 const sp<InputApplicationHandle>& applicationHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001202 const sp<InputWindowHandle>& windowHandle, nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001203 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001204 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001205 if (DEBUG_FOCUS) {
1206 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1207 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001208 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1209 mInputTargetWaitStartTime = currentTime;
1210 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1211 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001212 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001213 }
1214 } else {
1215 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001216 if (DEBUG_FOCUS) {
1217 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
1218 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), reason);
1219 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001220 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001221 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001222 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001223 } else if (applicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001224 timeout =
1225 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001226 } else {
1227 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1228 }
1229
1230 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1231 mInputTargetWaitStartTime = currentTime;
1232 mInputTargetWaitTimeoutTime = currentTime + timeout;
1233 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001234 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001235
Yi Kong9b14ac62018-07-17 13:48:38 -07001236 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001237 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001238 }
Robert Carr740167f2018-10-11 19:03:41 -07001239 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1240 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001241 }
1242 }
1243 }
1244
1245 if (mInputTargetWaitTimeoutExpired) {
1246 return INPUT_EVENT_INJECTION_TIMED_OUT;
1247 }
1248
1249 if (currentTime >= mInputTargetWaitTimeoutTime) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001250 onANRLocked(currentTime, applicationHandle, windowHandle, entry.eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001251 mInputTargetWaitStartTime, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001252
1253 // Force poll loop to wake up immediately on next iteration once we get the
1254 // ANR response back from the policy.
1255 *nextWakeupTime = LONG_LONG_MIN;
1256 return INPUT_EVENT_INJECTION_PENDING;
1257 } else {
1258 // Force poll loop to wake up when timeout is due.
1259 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1260 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1261 }
1262 return INPUT_EVENT_INJECTION_PENDING;
1263 }
1264}
1265
Robert Carr803535b2018-08-02 16:38:15 -07001266void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1267 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1268 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1269 state.removeWindowByToken(token);
1270 }
1271}
1272
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001273void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001274 nsecs_t newTimeout, const sp<IBinder>& inputConnectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001275 if (newTimeout > 0) {
1276 // Extend the timeout.
1277 mInputTargetWaitTimeoutTime = now() + newTimeout;
1278 } else {
1279 // Give up.
1280 mInputTargetWaitTimeoutExpired = true;
1281
1282 // Input state will not be realistic. Mark it out of sync.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001283 sp<Connection> connection = getConnectionLocked(inputConnectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001284 if (connection != nullptr) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001285 removeWindowByTokenLocked(inputConnectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001286
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001287 if (connection->status == Connection::STATUS_NORMAL) {
1288 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1289 "application not responding");
1290 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001291 }
1292 }
1293 }
1294}
1295
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001296nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001297 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1298 return currentTime - mInputTargetWaitStartTime;
1299 }
1300 return 0;
1301}
1302
1303void InputDispatcher::resetANRTimeoutsLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001304 if (DEBUG_FOCUS) {
1305 ALOGD("Resetting ANR timeouts.");
1306 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001307
1308 // Reset input target wait timeout.
1309 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001310 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001311}
1312
Tiger Huang721e26f2018-07-24 22:26:19 +08001313/**
1314 * Get the display id that the given event should go to. If this event specifies a valid display id,
1315 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1316 * Focused display is the display that the user most recently interacted with.
1317 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001318int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001319 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001320 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001321 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001322 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1323 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001324 break;
1325 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001326 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001327 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1328 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001329 break;
1330 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001331 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001332 case EventEntry::Type::CONFIGURATION_CHANGED:
1333 case EventEntry::Type::DEVICE_RESET: {
1334 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001335 return ADISPLAY_ID_NONE;
1336 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001337 }
1338 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1339}
1340
Michael Wrightd02c5b62014-02-10 15:10:22 -08001341int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001342 const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001343 std::vector<InputTarget>& inputTargets,
1344 nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001345 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001346 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001347
Tiger Huang721e26f2018-07-24 22:26:19 +08001348 int32_t displayId = getTargetDisplayId(entry);
1349 sp<InputWindowHandle> focusedWindowHandle =
1350 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1351 sp<InputApplicationHandle> focusedApplicationHandle =
1352 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1353
Michael Wrightd02c5b62014-02-10 15:10:22 -08001354 // If there is no currently focused window and no focused application
1355 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001356 if (focusedWindowHandle == nullptr) {
1357 if (focusedApplicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001358 injectionResult =
1359 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1360 nullptr, nextWakeupTime,
1361 "Waiting because no window has focus but there is "
1362 "a focused application that may eventually add a "
1363 "window when it finishes starting up.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001364 goto Unresponsive;
1365 }
1366
Arthur Hung3b413f22018-10-26 18:05:34 +08001367 ALOGI("Dropping event because there is no focused window or focused application in display "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001368 "%" PRId32 ".",
1369 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001370 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1371 goto Failed;
1372 }
1373
1374 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001375 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001376 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1377 goto Failed;
1378 }
1379
Jeff Brownffb49772014-10-10 19:01:34 -07001380 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001381 reason = checkWindowReadyForMoreInputLocked(currentTime, focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001382 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001383 injectionResult =
1384 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1385 focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001386 goto Unresponsive;
1387 }
1388
1389 // Success! Output targets.
1390 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001391 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001392 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1393 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001394
1395 // Done.
1396Failed:
1397Unresponsive:
1398 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001399 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001400 if (DEBUG_FOCUS) {
1401 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1402 "timeSpentWaitingForApplication=%0.1fms",
1403 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1404 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001405 return injectionResult;
1406}
1407
1408int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001409 const MotionEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001410 std::vector<InputTarget>& inputTargets,
1411 nsecs_t* nextWakeupTime,
1412 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001413 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001414 enum InjectionPermission {
1415 INJECTION_PERMISSION_UNKNOWN,
1416 INJECTION_PERMISSION_GRANTED,
1417 INJECTION_PERMISSION_DENIED
1418 };
1419
Michael Wrightd02c5b62014-02-10 15:10:22 -08001420 // For security reasons, we defer updating the touch state until we are sure that
1421 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001422 int32_t displayId = entry.displayId;
1423 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001424 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1425
1426 // Update the touch state as needed based on the properties of the touch event.
1427 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1428 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1429 sp<InputWindowHandle> newHoverWindowHandle;
1430
Jeff Brownf086ddb2014-02-11 14:28:48 -08001431 // Copy current touch state into mTempTouchState.
1432 // This state is always reset at the end of this function, so if we don't find state
1433 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001434 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001435 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1436 if (oldStateIndex >= 0) {
1437 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1438 mTempTouchState.copyFrom(*oldState);
1439 }
1440
1441 bool isSplit = mTempTouchState.split;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001442 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0 &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001443 (mTempTouchState.deviceId != entry.deviceId || mTempTouchState.source != entry.source ||
1444 mTempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001445 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1446 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1447 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1448 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1449 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001450 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001451 bool wrongDevice = false;
1452 if (newGesture) {
1453 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001454 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001455 if (DEBUG_FOCUS) {
1456 ALOGD("Dropping event because a pointer for a different device is already down "
1457 "in display %" PRId32,
1458 displayId);
1459 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001460 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001461 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1462 switchedDevice = false;
1463 wrongDevice = true;
1464 goto Failed;
1465 }
1466 mTempTouchState.reset();
1467 mTempTouchState.down = down;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001468 mTempTouchState.deviceId = entry.deviceId;
1469 mTempTouchState.source = entry.source;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001470 mTempTouchState.displayId = displayId;
1471 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001472 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001473 if (DEBUG_FOCUS) {
1474 ALOGI("Dropping move event because a pointer for a different device is already active "
1475 "in display %" PRId32,
1476 displayId);
1477 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001478 // TODO: test multiple simultaneous input streams.
1479 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1480 switchedDevice = false;
1481 wrongDevice = true;
1482 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001483 }
1484
1485 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1486 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1487
Garfield Tan00f511d2019-06-12 16:55:40 -07001488 int32_t x;
1489 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001490 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001491 // Always dispatch mouse events to cursor position.
1492 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001493 x = int32_t(entry.xCursorPosition);
1494 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001495 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001496 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1497 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001498 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001499 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001500 sp<InputWindowHandle> newTouchedWindowHandle =
1501 findTouchedWindowAtLocked(displayId, x, y, isDown /*addOutsideTargets*/,
1502 true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001503
1504 std::vector<TouchedMonitor> newGestureMonitors = isDown
1505 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1506 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001507
Michael Wrightd02c5b62014-02-10 15:10:22 -08001508 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001509 if (newTouchedWindowHandle != nullptr &&
1510 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001511 // New window supports splitting, but we should never split mouse events.
1512 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001513 } else if (isSplit) {
1514 // New window does not support splitting but we have already split events.
1515 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001516 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001517 }
1518
1519 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001520 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001521 // Try to assign the pointer to the first foreground window we find, if there is one.
1522 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001523 }
1524
1525 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1526 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001527 "(%d, %d) in display %" PRId32 ".",
1528 x, y, displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00001529 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1530 goto Failed;
1531 }
1532
1533 if (newTouchedWindowHandle != nullptr) {
1534 // Set target flags.
1535 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1536 if (isSplit) {
1537 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001538 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001539 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1540 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1541 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1542 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1543 }
1544
1545 // Update hover state.
1546 if (isHoverAction) {
1547 newHoverWindowHandle = newTouchedWindowHandle;
1548 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1549 newHoverWindowHandle = mLastHoverWindowHandle;
1550 }
1551
1552 // Update the temporary touch state.
1553 BitSet32 pointerIds;
1554 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001555 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001556 pointerIds.markBit(pointerId);
1557 }
1558 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001559 }
1560
Michael Wright3dd60e22019-03-27 22:06:44 +00001561 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001562 } else {
1563 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1564
1565 // If the pointer is not currently down, then ignore the event.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001566 if (!mTempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001567 if (DEBUG_FOCUS) {
1568 ALOGD("Dropping event because the pointer is not down or we previously "
1569 "dropped the pointer down event in display %" PRId32,
1570 displayId);
1571 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001572 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1573 goto Failed;
1574 }
1575
1576 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001577 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001578 mTempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001579 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1580 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001581
1582 sp<InputWindowHandle> oldTouchedWindowHandle =
1583 mTempTouchState.getFirstForegroundWindowHandle();
1584 sp<InputWindowHandle> newTouchedWindowHandle =
1585 findTouchedWindowAtLocked(displayId, x, y);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001586 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1587 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001588 if (DEBUG_FOCUS) {
1589 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1590 oldTouchedWindowHandle->getName().c_str(),
1591 newTouchedWindowHandle->getName().c_str(), displayId);
1592 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001593 // Make a slippery exit from the old window.
1594 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001595 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1596 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001597
1598 // Make a slippery entrance into the new window.
1599 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1600 isSplit = true;
1601 }
1602
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001603 int32_t targetFlags =
1604 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605 if (isSplit) {
1606 targetFlags |= InputTarget::FLAG_SPLIT;
1607 }
1608 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1609 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1610 }
1611
1612 BitSet32 pointerIds;
1613 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001614 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001615 }
1616 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1617 }
1618 }
1619 }
1620
1621 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1622 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001623 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001624#if DEBUG_HOVER
1625 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001626 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001627#endif
1628 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001629 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT,
1630 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001631 }
1632
1633 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001634 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001635#if DEBUG_HOVER
1636 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001637 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001638#endif
1639 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001640 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1641 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001642 }
1643 }
1644
1645 // Check permission to inject into all touched foreground windows and ensure there
1646 // is at least one touched foreground window.
1647 {
1648 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001649 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001650 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1651 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001652 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001653 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1654 injectionPermission = INJECTION_PERMISSION_DENIED;
1655 goto Failed;
1656 }
1657 }
1658 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001659 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1660 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001661 if (DEBUG_FOCUS) {
1662 ALOGD("Dropping event because there is no touched foreground window in display "
1663 "%" PRId32 " or gesture monitor to receive it.",
1664 displayId);
1665 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001666 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1667 goto Failed;
1668 }
1669
1670 // Permission granted to injection into all touched foreground windows.
1671 injectionPermission = INJECTION_PERMISSION_GRANTED;
1672 }
1673
1674 // Check whether windows listening for outside touches are owned by the same UID. If it is
1675 // set the policy flag that we will not reveal coordinate information to this window.
1676 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1677 sp<InputWindowHandle> foregroundWindowHandle =
1678 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001679 if (foregroundWindowHandle) {
1680 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1681 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1682 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1683 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1684 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1685 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001686 InputTarget::FLAG_ZERO_COORDS,
1687 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001688 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001689 }
1690 }
1691 }
1692 }
1693
1694 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001695 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001696 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001697 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001698 std::string reason =
1699 checkWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle,
1700 entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001701 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001702 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, nullptr,
1703 touchedWindow.windowHandle,
1704 nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001705 goto Unresponsive;
1706 }
1707 }
1708 }
1709
1710 // If this is the first pointer going down and the touched window has a wallpaper
1711 // then also add the touched wallpaper windows so they are locked in for the duration
1712 // of the touch gesture.
1713 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1714 // engine only supports touch events. We would need to add a mechanism similar
1715 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1716 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1717 sp<InputWindowHandle> foregroundWindowHandle =
1718 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001719 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001720 const std::vector<sp<InputWindowHandle>> windowHandles =
1721 getWindowHandlesLocked(displayId);
1722 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001723 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001724 if (info->displayId == displayId &&
1725 windowHandle->getInfo()->layoutParamsType == InputWindowInfo::TYPE_WALLPAPER) {
1726 mTempTouchState
1727 .addOrUpdateWindow(windowHandle,
1728 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1729 InputTarget::
1730 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1731 InputTarget::FLAG_DISPATCH_AS_IS,
1732 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001733 }
1734 }
1735 }
1736 }
1737
1738 // Success! Output targets.
1739 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1740
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001741 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001742 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001743 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001744 }
1745
Michael Wright3dd60e22019-03-27 22:06:44 +00001746 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1747 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001748 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00001749 }
1750
Michael Wrightd02c5b62014-02-10 15:10:22 -08001751 // Drop the outside or hover touch windows since we will not care about them
1752 // in the next iteration.
1753 mTempTouchState.filterNonAsIsTouchWindows();
1754
1755Failed:
1756 // Check injection permission once and for all.
1757 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001758 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001759 injectionPermission = INJECTION_PERMISSION_GRANTED;
1760 } else {
1761 injectionPermission = INJECTION_PERMISSION_DENIED;
1762 }
1763 }
1764
1765 // Update final pieces of touch state if the injector had permission.
1766 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1767 if (!wrongDevice) {
1768 if (switchedDevice) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001769 if (DEBUG_FOCUS) {
1770 ALOGD("Conflicting pointer actions: Switched to a different device.");
1771 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001772 *outConflictingPointerActions = true;
1773 }
1774
1775 if (isHoverAction) {
1776 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001777 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001778 if (DEBUG_FOCUS) {
1779 ALOGD("Conflicting pointer actions: Hover received while pointer was "
1780 "down.");
1781 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001782 *outConflictingPointerActions = true;
1783 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001784 mTempTouchState.reset();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001785 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1786 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001787 mTempTouchState.deviceId = entry.deviceId;
1788 mTempTouchState.source = entry.source;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001789 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001790 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001791 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
1792 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001793 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001794 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001795 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1796 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001797 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001798 if (DEBUG_FOCUS) {
1799 ALOGD("Conflicting pointer actions: Down received while already down.");
1800 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001801 *outConflictingPointerActions = true;
1802 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001803 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1804 // One pointer went up.
1805 if (isSplit) {
1806 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001807 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001808
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001809 for (size_t i = 0; i < mTempTouchState.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001810 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001811 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1812 touchedWindow.pointerIds.clearBit(pointerId);
1813 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001814 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001815 continue;
1816 }
1817 }
1818 i += 1;
1819 }
1820 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001821 }
1822
1823 // Save changes unless the action was scroll in which case the temporary touch
1824 // state was only valid for this one action.
1825 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1826 if (mTempTouchState.displayId >= 0) {
1827 if (oldStateIndex >= 0) {
1828 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1829 } else {
1830 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1831 }
1832 } else if (oldStateIndex >= 0) {
1833 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1834 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001835 }
1836
1837 // Update hover state.
1838 mLastHoverWindowHandle = newHoverWindowHandle;
1839 }
1840 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001841 if (DEBUG_FOCUS) {
1842 ALOGD("Not updating touch focus because injection was denied.");
1843 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001844 }
1845
1846Unresponsive:
1847 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1848 mTempTouchState.reset();
1849
1850 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001851 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001852 if (DEBUG_FOCUS) {
1853 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1854 "timeSpentWaitingForApplication=%0.1fms",
1855 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1856 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001857 return injectionResult;
1858}
1859
1860void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001861 int32_t targetFlags, BitSet32 pointerIds,
1862 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001863 std::vector<InputTarget>::iterator it =
1864 std::find_if(inputTargets.begin(), inputTargets.end(),
1865 [&windowHandle](const InputTarget& inputTarget) {
1866 return inputTarget.inputChannel->getConnectionToken() ==
1867 windowHandle->getToken();
1868 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00001869
Chavi Weingarten114b77f2020-01-15 22:35:10 +00001870 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001871
1872 if (it == inputTargets.end()) {
1873 InputTarget inputTarget;
1874 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1875 if (inputChannel == nullptr) {
1876 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1877 return;
1878 }
1879 inputTarget.inputChannel = inputChannel;
1880 inputTarget.flags = targetFlags;
1881 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
1882 inputTargets.push_back(inputTarget);
1883 it = inputTargets.end() - 1;
1884 }
1885
1886 ALOG_ASSERT(it->flags == targetFlags);
1887 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
1888
1889 it->addPointers(pointerIds, -windowInfo->frameLeft, -windowInfo->frameTop,
1890 windowInfo->windowXScale, windowInfo->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001891}
1892
Michael Wright3dd60e22019-03-27 22:06:44 +00001893void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001894 int32_t displayId, float xOffset,
1895 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001896 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1897 mGlobalMonitorsByDisplay.find(displayId);
1898
1899 if (it != mGlobalMonitorsByDisplay.end()) {
1900 const std::vector<Monitor>& monitors = it->second;
1901 for (const Monitor& monitor : monitors) {
1902 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001903 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001904 }
1905}
1906
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001907void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
1908 float yOffset,
1909 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001910 InputTarget target;
1911 target.inputChannel = monitor.inputChannel;
1912 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001913 target.setDefaultPointerInfo(xOffset, yOffset, 1 /* windowXScale */, 1 /* windowYScale */);
Michael Wright3dd60e22019-03-27 22:06:44 +00001914 inputTargets.push_back(target);
1915}
1916
Michael Wrightd02c5b62014-02-10 15:10:22 -08001917bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001918 const InjectionState* injectionState) {
1919 if (injectionState &&
1920 (windowHandle == nullptr ||
1921 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
1922 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001923 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001924 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001925 "owned by uid %d",
1926 injectionState->injectorPid, injectionState->injectorUid,
1927 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001928 } else {
1929 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001930 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001931 }
1932 return false;
1933 }
1934 return true;
1935}
1936
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001937bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
1938 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001939 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001940 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1941 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001942 if (otherHandle == windowHandle) {
1943 break;
1944 }
1945
1946 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001947 if (otherInfo->displayId == displayId && otherInfo->visible &&
1948 !otherInfo->isTrustedOverlay() && otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001949 return true;
1950 }
1951 }
1952 return false;
1953}
1954
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001955bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1956 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001957 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001958 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001959 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001960 if (otherHandle == windowHandle) {
1961 break;
1962 }
1963
1964 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001965 if (otherInfo->displayId == displayId && otherInfo->visible &&
1966 !otherInfo->isTrustedOverlay() && otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001967 return true;
1968 }
1969 }
1970 return false;
1971}
1972
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001973std::string InputDispatcher::checkWindowReadyForMoreInputLocked(
1974 nsecs_t currentTime, const sp<InputWindowHandle>& windowHandle,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001975 const EventEntry& eventEntry, const char* targetType) {
Jeff Brownffb49772014-10-10 19:01:34 -07001976 // If the window is paused then keep waiting.
1977 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001978 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001979 }
1980
1981 // If the window's connection is not registered then keep waiting.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001982 sp<Connection> connection = getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001983 if (connection == nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001984 return StringPrintf("Waiting because the %s window's input channel is not "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001985 "registered with the input dispatcher. The window may be in the "
1986 "process of being removed.",
1987 targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001988 }
1989
1990 // If the connection is dead then keep waiting.
Jeff Brownffb49772014-10-10 19:01:34 -07001991 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001992 return StringPrintf("Waiting because the %s window's input connection is %s."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001993 "The window may be in the process of being removed.",
1994 targetType, connection->getStatusLabel());
Jeff Brownffb49772014-10-10 19:01:34 -07001995 }
1996
1997 // If the connection is backed up then keep waiting.
1998 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001999 return StringPrintf("Waiting because the %s window's input channel is full. "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002000 "Outbound queue length: %zu. Wait queue length: %zu.",
2001 targetType, connection->outboundQueue.size(),
2002 connection->waitQueue.size());
Jeff Brownffb49772014-10-10 19:01:34 -07002003 }
2004
2005 // Ensure that the dispatch queues aren't too far backed up for this event.
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002006 if (eventEntry.type == EventEntry::Type::KEY) {
Jeff Brownffb49772014-10-10 19:01:34 -07002007 // If the event is a key event, then we must wait for all previous events to
2008 // complete before delivering it because previous events may have the
2009 // side-effect of transferring focus to a different window and we want to
2010 // ensure that the following keys are sent to the new window.
2011 //
2012 // Suppose the user touches a button in a window then immediately presses "A".
2013 // If the button causes a pop-up window to appear then we want to ensure that
2014 // the "A" key is delivered to the new pop-up window. This is because users
2015 // often anticipate pending UI changes when typing on a keyboard.
2016 // To obtain this behavior, we must serialize key events with respect to all
2017 // prior input events.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002018 if (!connection->outboundQueue.empty() || !connection->waitQueue.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002019 return StringPrintf("Waiting to send key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002020 "finished processing all of the input events that were previously "
2021 "delivered to it. Outbound queue length: %zu. Wait queue length: "
2022 "%zu.",
2023 targetType, connection->outboundQueue.size(),
2024 connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002025 }
Jeff Brownffb49772014-10-10 19:01:34 -07002026 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002027 // Touch events can always be sent to a window immediately because the user intended
2028 // to touch whatever was visible at the time. Even if focus changes or a new
2029 // window appears moments later, the touch event was meant to be delivered to
2030 // whatever window happened to be on screen at the time.
2031 //
2032 // Generic motion events, such as trackball or joystick events are a little trickier.
2033 // Like key events, generic motion events are delivered to the focused window.
2034 // Unlike key events, generic motion events don't tend to transfer focus to other
2035 // windows and it is not important for them to be serialized. So we prefer to deliver
2036 // generic motion events as soon as possible to improve efficiency and reduce lag
2037 // through batching.
2038 //
2039 // The one case where we pause input event delivery is when the wait queue is piling
2040 // up with lots of events because the application is not responding.
2041 // This condition ensures that ANRs are detected reliably.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002042 if (!connection->waitQueue.empty() &&
2043 currentTime >=
2044 connection->waitQueue.front()->deliveryTime + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002045 return StringPrintf("Waiting to send non-key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002046 "finished processing certain input events that were delivered to "
2047 "it over "
2048 "%0.1fms ago. Wait queue length: %zu. Wait queue head age: "
2049 "%0.1fms.",
2050 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
2051 connection->waitQueue.size(),
2052 (currentTime - connection->waitQueue.front()->deliveryTime) *
2053 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002054 }
2055 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002056 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002057}
2058
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002059std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002060 const sp<InputApplicationHandle>& applicationHandle,
2061 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002062 if (applicationHandle != nullptr) {
2063 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002064 std::string label(applicationHandle->getName());
2065 label += " - ";
2066 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067 return label;
2068 } else {
2069 return applicationHandle->getName();
2070 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002071 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002072 return windowHandle->getName();
2073 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002074 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002075 }
2076}
2077
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002078void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002079 if (eventEntry.type == EventEntry::Type::FOCUS) {
2080 // Focus events are passed to apps, but do not represent user activity.
2081 return;
2082 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002083 int32_t displayId = getTargetDisplayId(eventEntry);
2084 sp<InputWindowHandle> focusedWindowHandle =
2085 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
2086 if (focusedWindowHandle != nullptr) {
2087 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002088 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
2089#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002090 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002091#endif
2092 return;
2093 }
2094 }
2095
2096 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002097 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002098 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002099 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2100 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002101 return;
2102 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002103
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002104 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002105 eventType = USER_ACTIVITY_EVENT_TOUCH;
2106 }
2107 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002108 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002109 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002110 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2111 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002112 return;
2113 }
2114 eventType = USER_ACTIVITY_EVENT_BUTTON;
2115 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002116 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002117 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002118 case EventEntry::Type::CONFIGURATION_CHANGED:
2119 case EventEntry::Type::DEVICE_RESET: {
2120 LOG_ALWAYS_FATAL("%s events are not user activity",
2121 EventEntry::typeToString(eventEntry.type));
2122 break;
2123 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002124 }
2125
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002126 std::unique_ptr<CommandEntry> commandEntry =
2127 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002128 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002129 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002130 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002131}
2132
2133void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002134 const sp<Connection>& connection,
2135 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002136 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002137 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002138 std::string message =
2139 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2140 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002141 ATRACE_NAME(message.c_str());
2142 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002143#if DEBUG_DISPATCH_CYCLE
2144 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002145 "globalScaleFactor=%f, pointerIds=0x%x %s",
2146 connection->getInputChannelName().c_str(), inputTarget.flags,
2147 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2148 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002149#endif
2150
2151 // Skip this event if the connection status is not normal.
2152 // We don't want to enqueue additional outbound events if the connection is broken.
2153 if (connection->status != Connection::STATUS_NORMAL) {
2154#if DEBUG_DISPATCH_CYCLE
2155 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002156 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002157#endif
2158 return;
2159 }
2160
2161 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002162 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2163 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2164 "Entry type %s should not have FLAG_SPLIT",
2165 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002166
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002167 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002168 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002169 MotionEntry* splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002170 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002171 if (!splitMotionEntry) {
2172 return; // split event was dropped
2173 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002174 if (DEBUG_FOCUS) {
2175 ALOGD("channel '%s' ~ Split motion event.",
2176 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002177 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002178 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002179 enqueueDispatchEntriesLocked(currentTime, connection, splitMotionEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002180 splitMotionEntry->release();
2181 return;
2182 }
2183 }
2184
2185 // Not splitting. Enqueue dispatch entries for the event as is.
2186 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2187}
2188
2189void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002190 const sp<Connection>& connection,
2191 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002192 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002193 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002194 std::string message =
2195 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32
2196 ")",
2197 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002198 ATRACE_NAME(message.c_str());
2199 }
2200
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002201 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002202
2203 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002204 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002205 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002206 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002207 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002208 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002209 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002210 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002211 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002212 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002213 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002214 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002215 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002216
2217 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002218 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002219 startDispatchCycleLocked(currentTime, connection);
2220 }
2221}
2222
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002223void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
2224 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002225 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002226 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002227 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002228 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2229 connection->getInputChannelName().c_str(),
2230 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002231 ATRACE_NAME(message.c_str());
2232 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002233 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002234 if (!(inputTargetFlags & dispatchMode)) {
2235 return;
2236 }
2237 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2238
2239 // This is a new event.
2240 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002241 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002242 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002243
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002244 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2245 // different EventEntry than what was passed in.
2246 EventEntry* newEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002247 // Apply target flags and update the connection's input state.
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002248 switch (newEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002249 case EventEntry::Type::KEY: {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002250 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*newEntry);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002251 dispatchEntry->resolvedAction = keyEntry.action;
2252 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002253
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002254 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2255 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002256#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002257 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2258 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002259#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002260 return; // skip the inconsistent event
2261 }
2262 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002263 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002264
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002265 case EventEntry::Type::MOTION: {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002266 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*newEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002267 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2268 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2269 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2270 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2271 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2272 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2273 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2274 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2275 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2276 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2277 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002278 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002279 }
2280 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002281 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2282 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002283#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002284 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2285 "event",
2286 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002287#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002288 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2289 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002290
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002291 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002292 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2293 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2294 }
2295 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2296 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2297 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002298
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002299 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2300 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002301#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002302 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2303 "event",
2304 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002305#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002306 return; // skip the inconsistent event
2307 }
2308
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002309 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002310 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002311
2312 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002313 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002314 case EventEntry::Type::FOCUS: {
2315 break;
2316 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002317 case EventEntry::Type::CONFIGURATION_CHANGED:
2318 case EventEntry::Type::DEVICE_RESET: {
2319 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002320 EventEntry::typeToString(newEntry->type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002321 break;
2322 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002323 }
2324
2325 // Remember that we are waiting for this dispatch to complete.
2326 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002327 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002328 }
2329
2330 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002331 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002332 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002333}
2334
chaviwfd6d3512019-03-25 13:23:49 -07002335void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002336 const sp<IBinder>& newToken) {
chaviw8c9cf542019-03-25 13:02:48 -07002337 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002338 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2339 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002340 return;
2341 }
2342
2343 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2344 if (inputWindowHandle == nullptr) {
2345 return;
2346 }
2347
chaviw8c9cf542019-03-25 13:02:48 -07002348 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002349 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002350
2351 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2352
2353 if (!hasFocusChanged) {
2354 return;
2355 }
2356
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002357 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2358 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002359 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002360 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002361}
2362
2363void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002364 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002365 if (ATRACE_ENABLED()) {
2366 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002367 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002368 ATRACE_NAME(message.c_str());
2369 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002370#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002371 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002372#endif
2373
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002374 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2375 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002376 dispatchEntry->deliveryTime = currentTime;
2377
2378 // Publish the event.
2379 status_t status;
2380 EventEntry* eventEntry = dispatchEntry->eventEntry;
2381 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002382 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002383 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002384
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002385 // Publish the key event.
2386 status = connection->inputPublisher
2387 .publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId,
2388 keyEntry->source, keyEntry->displayId,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06002389 INVALID_HMAC, dispatchEntry->resolvedAction,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002390 dispatchEntry->resolvedFlags, keyEntry->keyCode,
2391 keyEntry->scanCode, keyEntry->metaState,
2392 keyEntry->repeatCount, keyEntry->downTime,
2393 keyEntry->eventTime);
2394 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002395 }
2396
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002397 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002398 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002399
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002400 PointerCoords scaledCoords[MAX_POINTERS];
2401 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2402
chaviw82357092020-01-28 13:13:06 -08002403 // Set the X and Y offset and X and Y scale depending on the input source.
2404 float xOffset = 0.0f, yOffset = 0.0f;
2405 float xScale = 1.0f, yScale = 1.0f;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002406 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
2407 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2408 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002409 xScale = dispatchEntry->windowXScale;
2410 yScale = dispatchEntry->windowYScale;
2411 xOffset = dispatchEntry->xOffset * xScale;
2412 yOffset = dispatchEntry->yOffset * yScale;
2413 if (globalScaleFactor != 1.0f) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002414 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2415 scaledCoords[i] = motionEntry->pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002416 // Don't apply window scale here since we don't want scale to affect raw
2417 // coordinates. The scale will be sent back to the client and applied
2418 // later when requesting relative coordinates.
2419 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2420 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002421 }
2422 usingCoords = scaledCoords;
2423 }
2424 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002425 // We don't want the dispatch target to know.
2426 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
2427 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2428 scaledCoords[i].clear();
2429 }
2430 usingCoords = scaledCoords;
2431 }
2432 }
2433
2434 // Publish the motion event.
2435 status = connection->inputPublisher
2436 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2437 motionEntry->source, motionEntry->displayId,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06002438 INVALID_HMAC, dispatchEntry->resolvedAction,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002439 motionEntry->actionButton,
2440 dispatchEntry->resolvedFlags,
2441 motionEntry->edgeFlags, motionEntry->metaState,
2442 motionEntry->buttonState,
chaviw82357092020-01-28 13:13:06 -08002443 motionEntry->classification, xScale, yScale,
2444 xOffset, yOffset, motionEntry->xPrecision,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002445 motionEntry->yPrecision,
2446 motionEntry->xCursorPosition,
2447 motionEntry->yCursorPosition,
2448 motionEntry->downTime, motionEntry->eventTime,
2449 motionEntry->pointerCount,
2450 motionEntry->pointerProperties, usingCoords);
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05002451 reportTouchEventForStatistics(*motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002452 break;
2453 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002454 case EventEntry::Type::FOCUS: {
2455 FocusEntry* focusEntry = static_cast<FocusEntry*>(eventEntry);
2456 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
2457 focusEntry->hasFocus,
2458 mInTouchMode);
2459 break;
2460 }
2461
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002462 case EventEntry::Type::CONFIGURATION_CHANGED:
2463 case EventEntry::Type::DEVICE_RESET: {
2464 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
2465 EventEntry::typeToString(eventEntry->type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002466 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002467 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002468 }
2469
2470 // Check the result.
2471 if (status) {
2472 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002473 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002474 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002475 "This is unexpected because the wait queue is empty, so the pipe "
2476 "should be empty and we shouldn't have any problems writing an "
2477 "event to it, status=%d",
2478 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002479 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2480 } else {
2481 // Pipe is full and we are waiting for the app to finish process some events
2482 // before sending more events to it.
2483#if DEBUG_DISPATCH_CYCLE
2484 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002485 "waiting for the application to catch up",
2486 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002487#endif
2488 connection->inputPublisherBlocked = true;
2489 }
2490 } else {
2491 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002492 "status=%d",
2493 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002494 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2495 }
2496 return;
2497 }
2498
2499 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002500 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2501 connection->outboundQueue.end(),
2502 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002503 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002504 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002505 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002506 }
2507}
2508
2509void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002510 const sp<Connection>& connection, uint32_t seq,
2511 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002512#if DEBUG_DISPATCH_CYCLE
2513 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002514 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002515#endif
2516
2517 connection->inputPublisherBlocked = false;
2518
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002519 if (connection->status == Connection::STATUS_BROKEN ||
2520 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002521 return;
2522 }
2523
2524 // Notify other system components and prepare to start the next dispatch cycle.
2525 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2526}
2527
2528void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002529 const sp<Connection>& connection,
2530 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002531#if DEBUG_DISPATCH_CYCLE
2532 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002533 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002534#endif
2535
2536 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002537 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002538 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002539 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002540 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002541
2542 // The connection appears to be unrecoverably broken.
2543 // Ignore already broken or zombie connections.
2544 if (connection->status == Connection::STATUS_NORMAL) {
2545 connection->status = Connection::STATUS_BROKEN;
2546
2547 if (notify) {
2548 // Notify other system components.
2549 onDispatchCycleBrokenLocked(currentTime, connection);
2550 }
2551 }
2552}
2553
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002554void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2555 while (!queue.empty()) {
2556 DispatchEntry* dispatchEntry = queue.front();
2557 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002558 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002559 }
2560}
2561
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002562void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002563 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002564 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002565 }
2566 delete dispatchEntry;
2567}
2568
2569int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2570 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2571
2572 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002573 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002574
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002575 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002576 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002577 "fd=%d, events=0x%x",
2578 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002579 return 0; // remove the callback
2580 }
2581
2582 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002583 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002584 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2585 if (!(events & ALOOPER_EVENT_INPUT)) {
2586 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002587 "events=0x%x",
2588 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002589 return 1;
2590 }
2591
2592 nsecs_t currentTime = now();
2593 bool gotOne = false;
2594 status_t status;
2595 for (;;) {
2596 uint32_t seq;
2597 bool handled;
2598 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2599 if (status) {
2600 break;
2601 }
2602 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2603 gotOne = true;
2604 }
2605 if (gotOne) {
2606 d->runCommandsLockedInterruptible();
2607 if (status == WOULD_BLOCK) {
2608 return 1;
2609 }
2610 }
2611
2612 notify = status != DEAD_OBJECT || !connection->monitor;
2613 if (notify) {
2614 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002615 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002616 }
2617 } else {
2618 // Monitor channels are never explicitly unregistered.
2619 // We do it automatically when the remote endpoint is closed so don't warn
2620 // about them.
2621 notify = !connection->monitor;
2622 if (notify) {
2623 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002624 "events=0x%x",
2625 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002626 }
2627 }
2628
2629 // Unregister the channel.
2630 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2631 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002632 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08002633}
2634
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002635void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002636 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002637 for (const auto& pair : mConnectionsByFd) {
2638 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002639 }
2640}
2641
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002642void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002643 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002644 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2645 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2646}
2647
2648void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2649 const CancelationOptions& options,
2650 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2651 for (const auto& it : monitorsByDisplay) {
2652 const std::vector<Monitor>& monitors = it.second;
2653 for (const Monitor& monitor : monitors) {
2654 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002655 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002656 }
2657}
2658
Michael Wrightd02c5b62014-02-10 15:10:22 -08002659void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2660 const sp<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002661 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002662 if (connection == nullptr) {
2663 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002664 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002665
2666 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002667}
2668
2669void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2670 const sp<Connection>& connection, const CancelationOptions& options) {
2671 if (connection->status == Connection::STATUS_BROKEN) {
2672 return;
2673 }
2674
2675 nsecs_t currentTime = now();
2676
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07002677 std::vector<EventEntry*> cancelationEvents =
2678 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002679
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002680 if (cancelationEvents.empty()) {
2681 return;
2682 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002683#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002684 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
2685 "with reality: %s, mode=%d.",
2686 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
2687 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002688#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08002689
2690 InputTarget target;
2691 sp<InputWindowHandle> windowHandle =
2692 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
2693 if (windowHandle != nullptr) {
2694 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2695 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2696 windowInfo->windowXScale, windowInfo->windowYScale);
2697 target.globalScaleFactor = windowInfo->globalScaleFactor;
2698 }
2699 target.inputChannel = connection->inputChannel;
2700 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2701
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002702 for (size_t i = 0; i < cancelationEvents.size(); i++) {
2703 EventEntry* cancelationEventEntry = cancelationEvents[i];
2704 switch (cancelationEventEntry->type) {
2705 case EventEntry::Type::KEY: {
2706 logOutboundKeyDetails("cancel - ",
2707 static_cast<const KeyEntry&>(*cancelationEventEntry));
2708 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002709 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002710 case EventEntry::Type::MOTION: {
2711 logOutboundMotionDetails("cancel - ",
2712 static_cast<const MotionEntry&>(*cancelationEventEntry));
2713 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002714 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002715 case EventEntry::Type::FOCUS: {
2716 LOG_ALWAYS_FATAL("Canceling focus events is not supported");
2717 break;
2718 }
2719 case EventEntry::Type::CONFIGURATION_CHANGED:
2720 case EventEntry::Type::DEVICE_RESET: {
2721 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2722 EventEntry::typeToString(cancelationEventEntry->type));
2723 break;
2724 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002725 }
2726
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002727 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
2728 target, InputTarget::FLAG_DISPATCH_AS_IS);
2729
2730 cancelationEventEntry->release();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002731 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002732
2733 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002734}
2735
Svet Ganov5d3bc372020-01-26 23:11:07 -08002736void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
2737 const sp<Connection>& connection) {
2738 if (connection->status == Connection::STATUS_BROKEN) {
2739 return;
2740 }
2741
2742 nsecs_t currentTime = now();
2743
2744 std::vector<EventEntry*> downEvents =
2745 connection->inputState.synthesizePointerDownEvents(currentTime);
2746
2747 if (downEvents.empty()) {
2748 return;
2749 }
2750
2751#if DEBUG_OUTBOUND_EVENT_DETAILS
2752 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
2753 connection->getInputChannelName().c_str(), downEvents.size());
2754#endif
2755
2756 InputTarget target;
2757 sp<InputWindowHandle> windowHandle =
2758 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
2759 if (windowHandle != nullptr) {
2760 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2761 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2762 windowInfo->windowXScale, windowInfo->windowYScale);
2763 target.globalScaleFactor = windowInfo->globalScaleFactor;
2764 }
2765 target.inputChannel = connection->inputChannel;
2766 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2767
2768 for (EventEntry* downEventEntry : downEvents) {
2769 switch (downEventEntry->type) {
2770 case EventEntry::Type::MOTION: {
2771 logOutboundMotionDetails("down - ",
2772 static_cast<const MotionEntry&>(*downEventEntry));
2773 break;
2774 }
2775
2776 case EventEntry::Type::KEY:
2777 case EventEntry::Type::FOCUS:
2778 case EventEntry::Type::CONFIGURATION_CHANGED:
2779 case EventEntry::Type::DEVICE_RESET: {
2780 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2781 EventEntry::typeToString(downEventEntry->type));
2782 break;
2783 }
2784 }
2785
2786 enqueueDispatchEntryLocked(connection, downEventEntry, // increments ref
2787 target, InputTarget::FLAG_DISPATCH_AS_IS);
2788
2789 downEventEntry->release();
2790 }
2791
2792 startDispatchCycleLocked(currentTime, connection);
2793}
2794
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002795MotionEntry* InputDispatcher::splitMotionEvent(const MotionEntry& originalMotionEntry,
Garfield Tane84e6f92019-08-29 17:28:41 -07002796 BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002797 ALOG_ASSERT(pointerIds.value != 0);
2798
2799 uint32_t splitPointerIndexMap[MAX_POINTERS];
2800 PointerProperties splitPointerProperties[MAX_POINTERS];
2801 PointerCoords splitPointerCoords[MAX_POINTERS];
2802
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002803 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002804 uint32_t splitPointerCount = 0;
2805
2806 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002807 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002808 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002809 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002810 uint32_t pointerId = uint32_t(pointerProperties.id);
2811 if (pointerIds.hasBit(pointerId)) {
2812 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2813 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2814 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002815 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002816 splitPointerCount += 1;
2817 }
2818 }
2819
2820 if (splitPointerCount != pointerIds.count()) {
2821 // This is bad. We are missing some of the pointers that we expected to deliver.
2822 // Most likely this indicates that we received an ACTION_MOVE events that has
2823 // different pointer ids than we expected based on the previous ACTION_DOWN
2824 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2825 // in this way.
2826 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002827 "we expected there to be %d pointers. This probably means we received "
2828 "a broken sequence of pointer ids from the input device.",
2829 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002830 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002831 }
2832
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002833 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002834 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002835 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
2836 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002837 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2838 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002839 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002840 uint32_t pointerId = uint32_t(pointerProperties.id);
2841 if (pointerIds.hasBit(pointerId)) {
2842 if (pointerIds.count() == 1) {
2843 // The first/last pointer went down/up.
2844 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002845 ? AMOTION_EVENT_ACTION_DOWN
2846 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002847 } else {
2848 // A secondary pointer went down/up.
2849 uint32_t splitPointerIndex = 0;
2850 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2851 splitPointerIndex += 1;
2852 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002853 action = maskedAction |
2854 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002855 }
2856 } else {
2857 // An unrelated pointer changed.
2858 action = AMOTION_EVENT_ACTION_MOVE;
2859 }
2860 }
2861
Garfield Tan00f511d2019-06-12 16:55:40 -07002862 MotionEntry* splitMotionEntry =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002863 new MotionEntry(originalMotionEntry.sequenceNum, originalMotionEntry.eventTime,
2864 originalMotionEntry.deviceId, originalMotionEntry.source,
2865 originalMotionEntry.displayId, originalMotionEntry.policyFlags, action,
2866 originalMotionEntry.actionButton, originalMotionEntry.flags,
2867 originalMotionEntry.metaState, originalMotionEntry.buttonState,
2868 originalMotionEntry.classification, originalMotionEntry.edgeFlags,
2869 originalMotionEntry.xPrecision, originalMotionEntry.yPrecision,
2870 originalMotionEntry.xCursorPosition,
2871 originalMotionEntry.yCursorPosition, originalMotionEntry.downTime,
Garfield Tan00f511d2019-06-12 16:55:40 -07002872 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002873
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002874 if (originalMotionEntry.injectionState) {
2875 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002876 splitMotionEntry->injectionState->refCount += 1;
2877 }
2878
2879 return splitMotionEntry;
2880}
2881
2882void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2883#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002884 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002885#endif
2886
2887 bool needWake;
2888 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002889 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002890
Prabir Pradhan42611e02018-11-27 14:04:02 -08002891 ConfigurationChangedEntry* newEntry =
2892 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002893 needWake = enqueueInboundEventLocked(newEntry);
2894 } // release lock
2895
2896 if (needWake) {
2897 mLooper->wake();
2898 }
2899}
2900
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002901/**
2902 * If one of the meta shortcuts is detected, process them here:
2903 * Meta + Backspace -> generate BACK
2904 * Meta + Enter -> generate HOME
2905 * This will potentially overwrite keyCode and metaState.
2906 */
2907void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002908 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002909 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2910 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2911 if (keyCode == AKEYCODE_DEL) {
2912 newKeyCode = AKEYCODE_BACK;
2913 } else if (keyCode == AKEYCODE_ENTER) {
2914 newKeyCode = AKEYCODE_HOME;
2915 }
2916 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002917 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002918 struct KeyReplacement replacement = {keyCode, deviceId};
2919 mReplacedKeys.add(replacement, newKeyCode);
2920 keyCode = newKeyCode;
2921 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2922 }
2923 } else if (action == AKEY_EVENT_ACTION_UP) {
2924 // In order to maintain a consistent stream of up and down events, check to see if the key
2925 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2926 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002927 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002928 struct KeyReplacement replacement = {keyCode, deviceId};
2929 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2930 if (index >= 0) {
2931 keyCode = mReplacedKeys.valueAt(index);
2932 mReplacedKeys.removeItemsAt(index);
2933 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2934 }
2935 }
2936}
2937
Michael Wrightd02c5b62014-02-10 15:10:22 -08002938void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2939#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002940 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
2941 "policyFlags=0x%x, action=0x%x, "
2942 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
2943 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2944 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
2945 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002946#endif
2947 if (!validateKeyEvent(args->action)) {
2948 return;
2949 }
2950
2951 uint32_t policyFlags = args->policyFlags;
2952 int32_t flags = args->flags;
2953 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002954 // InputDispatcher tracks and generates key repeats on behalf of
2955 // whatever notifies it, so repeatCount should always be set to 0
2956 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002957 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2958 policyFlags |= POLICY_FLAG_VIRTUAL;
2959 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2960 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002961 if (policyFlags & POLICY_FLAG_FUNCTION) {
2962 metaState |= AMETA_FUNCTION_ON;
2963 }
2964
2965 policyFlags |= POLICY_FLAG_TRUSTED;
2966
Michael Wright78f24442014-08-06 15:55:28 -07002967 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002968 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002969
Michael Wrightd02c5b62014-02-10 15:10:22 -08002970 KeyEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06002971 event.initialize(args->deviceId, args->source, args->displayId, INVALID_HMAC, args->action,
2972 flags, keyCode, args->scanCode, metaState, repeatCount, args->downTime,
2973 args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002974
Michael Wright2b3c3302018-03-02 17:19:13 +00002975 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002976 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002977 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2978 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002979 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00002980 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002981
Michael Wrightd02c5b62014-02-10 15:10:22 -08002982 bool needWake;
2983 { // acquire lock
2984 mLock.lock();
2985
2986 if (shouldSendKeyToInputFilterLocked(args)) {
2987 mLock.unlock();
2988
2989 policyFlags |= POLICY_FLAG_FILTERED;
2990 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2991 return; // event was consumed by the filter
2992 }
2993
2994 mLock.lock();
2995 }
2996
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002997 KeyEntry* newEntry =
2998 new KeyEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2999 args->displayId, policyFlags, args->action, flags, keyCode,
3000 args->scanCode, metaState, repeatCount, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003001
3002 needWake = enqueueInboundEventLocked(newEntry);
3003 mLock.unlock();
3004 } // release lock
3005
3006 if (needWake) {
3007 mLooper->wake();
3008 }
3009}
3010
3011bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3012 return mInputFilterEnabled;
3013}
3014
3015void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3016#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08003017 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07003018 ", policyFlags=0x%x, "
3019 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3020 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003021 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07003022 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3023 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
Jaewan Kim372fbe42019-10-02 10:58:46 +09003024 args->edgeFlags, args->xPrecision, args->yPrecision, args->xCursorPosition,
Garfield Tan00f511d2019-06-12 16:55:40 -07003025 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003026 for (uint32_t i = 0; i < args->pointerCount; i++) {
3027 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003028 "x=%f, y=%f, pressure=%f, size=%f, "
3029 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3030 "orientation=%f",
3031 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3032 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3033 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3034 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3035 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3036 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3037 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3038 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3039 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3040 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003041 }
3042#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003043 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3044 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003045 return;
3046 }
3047
3048 uint32_t policyFlags = args->policyFlags;
3049 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003050
3051 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003052 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003053 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3054 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003055 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003056 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003057
3058 bool needWake;
3059 { // acquire lock
3060 mLock.lock();
3061
3062 if (shouldSendMotionToInputFilterLocked(args)) {
3063 mLock.unlock();
3064
3065 MotionEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06003066 event.initialize(args->deviceId, args->source, args->displayId, INVALID_HMAC,
3067 args->action, args->actionButton, args->flags, args->edgeFlags,
3068 args->metaState, args->buttonState, args->classification, 1 /*xScale*/,
3069 1 /*yScale*/, 0 /* xOffset */, 0 /* yOffset */, args->xPrecision,
Garfield Tan00f511d2019-06-12 16:55:40 -07003070 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3071 args->downTime, args->eventTime, args->pointerCount,
3072 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003073
3074 policyFlags |= POLICY_FLAG_FILTERED;
3075 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3076 return; // event was consumed by the filter
3077 }
3078
3079 mLock.lock();
3080 }
3081
3082 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07003083 MotionEntry* newEntry =
3084 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
3085 args->displayId, policyFlags, args->action, args->actionButton,
3086 args->flags, args->metaState, args->buttonState,
3087 args->classification, args->edgeFlags, args->xPrecision,
3088 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3089 args->downTime, args->pointerCount, args->pointerProperties,
3090 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003091
3092 needWake = enqueueInboundEventLocked(newEntry);
3093 mLock.unlock();
3094 } // release lock
3095
3096 if (needWake) {
3097 mLooper->wake();
3098 }
3099}
3100
3101bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003102 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003103}
3104
3105void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3106#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003107 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003108 "switchMask=0x%08x",
3109 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003110#endif
3111
3112 uint32_t policyFlags = args->policyFlags;
3113 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003114 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003115}
3116
3117void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3118#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003119 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3120 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003121#endif
3122
3123 bool needWake;
3124 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003125 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003126
Prabir Pradhan42611e02018-11-27 14:04:02 -08003127 DeviceResetEntry* newEntry =
3128 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003129 needWake = enqueueInboundEventLocked(newEntry);
3130 } // release lock
3131
3132 if (needWake) {
3133 mLooper->wake();
3134 }
3135}
3136
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003137int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid,
3138 int32_t injectorUid, int32_t syncMode,
3139 int32_t timeoutMillis, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003140#if DEBUG_INBOUND_EVENT_DETAILS
3141 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003142 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
3143 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003144#endif
3145
3146 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
3147
3148 policyFlags |= POLICY_FLAG_INJECTED;
3149 if (hasInjectionPermission(injectorPid, injectorUid)) {
3150 policyFlags |= POLICY_FLAG_TRUSTED;
3151 }
3152
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003153 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003154 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003155 case AINPUT_EVENT_TYPE_KEY: {
3156 KeyEvent keyEvent;
3157 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
3158 int32_t action = keyEvent.getAction();
3159 if (!validateKeyEvent(action)) {
3160 return INPUT_EVENT_INJECTION_FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003161 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003162
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003163 int32_t flags = keyEvent.getFlags();
3164 int32_t keyCode = keyEvent.getKeyCode();
3165 int32_t metaState = keyEvent.getMetaState();
3166 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
3167 /*byref*/ keyCode, /*byref*/ metaState);
3168 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(),
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06003169 keyEvent.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003170 keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
3171 keyEvent.getDownTime(), keyEvent.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003172
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003173 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3174 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003175 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003176
3177 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3178 android::base::Timer t;
3179 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3180 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3181 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3182 std::to_string(t.duration().count()).c_str());
3183 }
3184 }
3185
3186 mLock.lock();
3187 KeyEntry* injectedEntry =
3188 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
3189 keyEvent.getDeviceId(), keyEvent.getSource(),
3190 keyEvent.getDisplayId(), policyFlags, action, flags,
3191 keyEvent.getKeyCode(), keyEvent.getScanCode(),
3192 keyEvent.getMetaState(), keyEvent.getRepeatCount(),
3193 keyEvent.getDownTime());
3194 injectedEntries.push(injectedEntry);
3195 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003196 }
3197
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003198 case AINPUT_EVENT_TYPE_MOTION: {
3199 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3200 int32_t action = motionEvent->getAction();
3201 size_t pointerCount = motionEvent->getPointerCount();
3202 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3203 int32_t actionButton = motionEvent->getActionButton();
3204 int32_t displayId = motionEvent->getDisplayId();
3205 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
3206 return INPUT_EVENT_INJECTION_FAILED;
3207 }
3208
3209 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3210 nsecs_t eventTime = motionEvent->getEventTime();
3211 android::base::Timer t;
3212 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3213 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3214 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3215 std::to_string(t.duration().count()).c_str());
3216 }
3217 }
3218
3219 mLock.lock();
3220 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3221 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
3222 MotionEntry* injectedEntry =
Garfield Tan00f511d2019-06-12 16:55:40 -07003223 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3224 motionEvent->getDeviceId(), motionEvent->getSource(),
3225 motionEvent->getDisplayId(), policyFlags, action, actionButton,
3226 motionEvent->getFlags(), motionEvent->getMetaState(),
3227 motionEvent->getButtonState(), motionEvent->getClassification(),
3228 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3229 motionEvent->getYPrecision(),
3230 motionEvent->getRawXCursorPosition(),
3231 motionEvent->getRawYCursorPosition(),
3232 motionEvent->getDownTime(), uint32_t(pointerCount),
3233 pointerProperties, samplePointerCoords,
3234 motionEvent->getXOffset(), motionEvent->getYOffset());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003235 injectedEntries.push(injectedEntry);
3236 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3237 sampleEventTimes += 1;
3238 samplePointerCoords += pointerCount;
3239 MotionEntry* nextInjectedEntry =
3240 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3241 motionEvent->getDeviceId(), motionEvent->getSource(),
3242 motionEvent->getDisplayId(), policyFlags, action,
3243 actionButton, motionEvent->getFlags(),
3244 motionEvent->getMetaState(), motionEvent->getButtonState(),
3245 motionEvent->getClassification(),
3246 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3247 motionEvent->getYPrecision(),
3248 motionEvent->getRawXCursorPosition(),
3249 motionEvent->getRawYCursorPosition(),
3250 motionEvent->getDownTime(), uint32_t(pointerCount),
3251 pointerProperties, samplePointerCoords,
3252 motionEvent->getXOffset(), motionEvent->getYOffset());
3253 injectedEntries.push(nextInjectedEntry);
3254 }
3255 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003256 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003257
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003258 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003259 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003260 return INPUT_EVENT_INJECTION_FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003261 }
3262
3263 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3264 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3265 injectionState->injectionIsAsync = true;
3266 }
3267
3268 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003269 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003270
3271 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003272 while (!injectedEntries.empty()) {
3273 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3274 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003275 }
3276
3277 mLock.unlock();
3278
3279 if (needWake) {
3280 mLooper->wake();
3281 }
3282
3283 int32_t injectionResult;
3284 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003285 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003286
3287 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3288 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3289 } else {
3290 for (;;) {
3291 injectionResult = injectionState->injectionResult;
3292 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3293 break;
3294 }
3295
3296 nsecs_t remainingTimeout = endTime - now();
3297 if (remainingTimeout <= 0) {
3298#if DEBUG_INJECTION
3299 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003300 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003301#endif
3302 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3303 break;
3304 }
3305
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003306 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003307 }
3308
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003309 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED &&
3310 syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003311 while (injectionState->pendingForegroundDispatches != 0) {
3312#if DEBUG_INJECTION
3313 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003314 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003315#endif
3316 nsecs_t remainingTimeout = endTime - now();
3317 if (remainingTimeout <= 0) {
3318#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003319 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3320 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003321#endif
3322 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3323 break;
3324 }
3325
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003326 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327 }
3328 }
3329 }
3330
3331 injectionState->release();
3332 } // release lock
3333
3334#if DEBUG_INJECTION
3335 ALOGD("injectInputEvent - Finished with result %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003336 "injectorPid=%d, injectorUid=%d",
3337 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003338#endif
3339
3340 return injectionResult;
3341}
3342
3343bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003344 return injectorUid == 0 ||
3345 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003346}
3347
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003348void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003349 InjectionState* injectionState = entry->injectionState;
3350 if (injectionState) {
3351#if DEBUG_INJECTION
3352 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003353 "injectorPid=%d, injectorUid=%d",
3354 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003355#endif
3356
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003357 if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003358 // Log the outcome since the injector did not wait for the injection result.
3359 switch (injectionResult) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003360 case INPUT_EVENT_INJECTION_SUCCEEDED:
3361 ALOGV("Asynchronous input event injection succeeded.");
3362 break;
3363 case INPUT_EVENT_INJECTION_FAILED:
3364 ALOGW("Asynchronous input event injection failed.");
3365 break;
3366 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3367 ALOGW("Asynchronous input event injection permission denied.");
3368 break;
3369 case INPUT_EVENT_INJECTION_TIMED_OUT:
3370 ALOGW("Asynchronous input event injection timed out.");
3371 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003372 }
3373 }
3374
3375 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003376 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003377 }
3378}
3379
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003380void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003381 InjectionState* injectionState = entry->injectionState;
3382 if (injectionState) {
3383 injectionState->pendingForegroundDispatches += 1;
3384 }
3385}
3386
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003387void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003388 InjectionState* injectionState = entry->injectionState;
3389 if (injectionState) {
3390 injectionState->pendingForegroundDispatches -= 1;
3391
3392 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003393 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003394 }
3395 }
3396}
3397
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003398std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3399 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003400 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003401}
3402
Michael Wrightd02c5b62014-02-10 15:10:22 -08003403sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003404 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003405 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003406 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3407 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003408 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003409 return windowHandle;
3410 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003411 }
3412 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003413 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003414}
3415
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003416bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003417 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003418 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3419 for (const sp<InputWindowHandle>& handle : windowHandles) {
3420 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003421 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003422 ALOGE("Found window %s in display %" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003423 ", but it should belong to display %" PRId32,
3424 windowHandle->getName().c_str(), it.first,
3425 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003426 }
3427 return true;
3428 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003429 }
3430 }
3431 return false;
3432}
3433
Robert Carr5c8a0262018-10-03 16:30:44 -07003434sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3435 size_t count = mInputChannelsByToken.count(token);
3436 if (count == 0) {
3437 return nullptr;
3438 }
3439 return mInputChannelsByToken.at(token);
3440}
3441
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003442void InputDispatcher::updateWindowHandlesForDisplayLocked(
3443 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3444 if (inputWindowHandles.empty()) {
3445 // Remove all handles on a display if there are no windows left.
3446 mWindowHandlesByDisplay.erase(displayId);
3447 return;
3448 }
3449
3450 // Since we compare the pointer of input window handles across window updates, we need
3451 // to make sure the handle object for the same window stays unchanged across updates.
3452 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003453 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003454 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003455 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003456 }
3457
3458 std::vector<sp<InputWindowHandle>> newHandles;
3459 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3460 if (!handle->updateInfo()) {
3461 // handle no longer valid
3462 continue;
3463 }
3464
3465 const InputWindowInfo* info = handle->getInfo();
3466 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3467 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3468 const bool noInputChannel =
3469 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3470 const bool canReceiveInput =
3471 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3472 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3473 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003474 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003475 handle->getName().c_str());
3476 }
3477 continue;
3478 }
3479
3480 if (info->displayId != displayId) {
3481 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3482 handle->getName().c_str(), displayId, info->displayId);
3483 continue;
3484 }
3485
chaviwaf87b3e2019-10-01 16:59:28 -07003486 if (oldHandlesById.find(handle->getId()) != oldHandlesById.end()) {
3487 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003488 oldHandle->updateFrom(handle);
3489 newHandles.push_back(oldHandle);
3490 } else {
3491 newHandles.push_back(handle);
3492 }
3493 }
3494
3495 // Insert or replace
3496 mWindowHandlesByDisplay[displayId] = newHandles;
3497}
3498
Arthur Hungb92218b2018-08-14 12:00:21 +08003499/**
3500 * Called from InputManagerService, update window handle list by displayId that can receive input.
3501 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3502 * If set an empty list, remove all handles from the specific display.
3503 * For focused handle, check if need to change and send a cancel event to previous one.
3504 * For removed handle, check if need to send a cancel event if already in touch.
3505 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003506void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003507 int32_t displayId,
3508 const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003509 if (DEBUG_FOCUS) {
3510 std::string windowList;
3511 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
3512 windowList += iwh->getName() + " ";
3513 }
3514 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
3515 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003516 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003517 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003518
Arthur Hungb92218b2018-08-14 12:00:21 +08003519 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003520 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3521 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003522
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003523 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3524
Tiger Huang721e26f2018-07-24 22:26:19 +08003525 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003526 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003527 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3528 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3529 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3530 windowHandle->getInfo()->visible) {
3531 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003532 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003533 if (windowHandle == mLastHoverWindowHandle) {
3534 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003535 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003536 }
3537
3538 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003539 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003540 }
3541
Tiger Huang721e26f2018-07-24 22:26:19 +08003542 sp<InputWindowHandle> oldFocusedWindowHandle =
3543 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3544
chaviwaf87b3e2019-10-01 16:59:28 -07003545 if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003546 if (oldFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003547 if (DEBUG_FOCUS) {
3548 ALOGD("Focus left window: %s in display %" PRId32,
3549 oldFocusedWindowHandle->getName().c_str(), displayId);
3550 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003551 sp<InputChannel> focusedInputChannel =
3552 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003553 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003554 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003555 "focus left window");
3556 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003557 enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003558 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003559 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003560 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003561 if (newFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003562 if (DEBUG_FOCUS) {
3563 ALOGD("Focus entered window: %s in display %" PRId32,
3564 newFocusedWindowHandle->getName().c_str(), displayId);
3565 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003566 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003567 enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003568 }
Robert Carrf759f162018-11-13 12:57:11 -08003569
3570 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003571 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003572 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003573 }
3574
Arthur Hungb92218b2018-08-14 12:00:21 +08003575 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3576 if (stateIndex >= 0) {
3577 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003578 for (size_t i = 0; i < state.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003579 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003580 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003581 if (DEBUG_FOCUS) {
3582 ALOGD("Touched window was removed: %s in display %" PRId32,
3583 touchedWindow.windowHandle->getName().c_str(), displayId);
3584 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003585 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003586 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003587 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003588 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003589 "touched window was removed");
3590 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
3591 options);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003592 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003593 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003594 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003595 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003596 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003597 }
3598 }
3599
3600 // Release information for windows that are no longer present.
3601 // This ensures that unused input channels are released promptly.
3602 // Otherwise, they might stick around until the window handle is destroyed
3603 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003604 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003605 if (!hasWindowHandleLocked(oldWindowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003606 if (DEBUG_FOCUS) {
3607 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
3608 }
Arthur Hung3b413f22018-10-26 18:05:34 +08003609 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003610 }
3611 }
3612 } // release lock
3613
3614 // Wake up poll loop since it may need to make new input dispatching choices.
3615 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003616
3617 if (setInputWindowsListener) {
3618 setInputWindowsListener->onSetInputWindowsFinished();
3619 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003620}
3621
3622void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003623 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003624 if (DEBUG_FOCUS) {
3625 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
3626 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
3627 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003628 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003629 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003630
Tiger Huang721e26f2018-07-24 22:26:19 +08003631 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3632 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003633 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003634 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3635 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003636 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003637 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003638 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003639 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003640 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003641 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003642 oldFocusedApplicationHandle.clear();
3643 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003644 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003645 } // release lock
3646
3647 // Wake up poll loop since it may need to make new input dispatching choices.
3648 mLooper->wake();
3649}
3650
Tiger Huang721e26f2018-07-24 22:26:19 +08003651/**
3652 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3653 * the display not specified.
3654 *
3655 * We track any unreleased events for each window. If a window loses the ability to receive the
3656 * released event, we will send a cancel event to it. So when the focused display is changed, we
3657 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3658 * display. The display-specified events won't be affected.
3659 */
3660void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003661 if (DEBUG_FOCUS) {
3662 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3663 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003664 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003665 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003666
3667 if (mFocusedDisplayId != displayId) {
3668 sp<InputWindowHandle> oldFocusedWindowHandle =
3669 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3670 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003671 sp<InputChannel> inputChannel =
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003672 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003673 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003674 CancelationOptions
3675 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3676 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003677 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003678 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3679 }
3680 }
3681 mFocusedDisplayId = displayId;
3682
3683 // Sanity check
3684 sp<InputWindowHandle> newFocusedWindowHandle =
3685 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003686 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003687
Tiger Huang721e26f2018-07-24 22:26:19 +08003688 if (newFocusedWindowHandle == nullptr) {
3689 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3690 if (!mFocusedWindowHandlesByDisplay.empty()) {
3691 ALOGE("But another display has a focused window:");
3692 for (auto& it : mFocusedWindowHandlesByDisplay) {
3693 const int32_t displayId = it.first;
3694 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003695 ALOGE("Display #%" PRId32 " has focused window: '%s'\n", displayId,
3696 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003697 }
3698 }
3699 }
3700 }
3701
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003702 if (DEBUG_FOCUS) {
3703 logDispatchStateLocked();
3704 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003705 } // release lock
3706
3707 // Wake up poll loop since it may need to make new input dispatching choices.
3708 mLooper->wake();
3709}
3710
Michael Wrightd02c5b62014-02-10 15:10:22 -08003711void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003712 if (DEBUG_FOCUS) {
3713 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3714 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003715
3716 bool changed;
3717 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003718 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003719
3720 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3721 if (mDispatchFrozen && !frozen) {
3722 resetANRTimeoutsLocked();
3723 }
3724
3725 if (mDispatchEnabled && !enabled) {
3726 resetAndDropEverythingLocked("dispatcher is being disabled");
3727 }
3728
3729 mDispatchEnabled = enabled;
3730 mDispatchFrozen = frozen;
3731 changed = true;
3732 } else {
3733 changed = false;
3734 }
3735
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003736 if (DEBUG_FOCUS) {
3737 logDispatchStateLocked();
3738 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003739 } // release lock
3740
3741 if (changed) {
3742 // Wake up poll loop since it may need to make new input dispatching choices.
3743 mLooper->wake();
3744 }
3745}
3746
3747void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003748 if (DEBUG_FOCUS) {
3749 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3750 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003751
3752 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003753 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003754
3755 if (mInputFilterEnabled == enabled) {
3756 return;
3757 }
3758
3759 mInputFilterEnabled = enabled;
3760 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3761 } // release lock
3762
3763 // Wake up poll loop since there might be work to do to drop everything.
3764 mLooper->wake();
3765}
3766
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08003767void InputDispatcher::setInTouchMode(bool inTouchMode) {
3768 std::scoped_lock lock(mLock);
3769 mInTouchMode = inTouchMode;
3770}
3771
chaviwfbe5d9c2018-12-26 12:23:37 -08003772bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3773 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003774 if (DEBUG_FOCUS) {
3775 ALOGD("Trivial transfer to same window.");
3776 }
chaviwfbe5d9c2018-12-26 12:23:37 -08003777 return true;
3778 }
3779
Michael Wrightd02c5b62014-02-10 15:10:22 -08003780 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003781 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003782
chaviwfbe5d9c2018-12-26 12:23:37 -08003783 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3784 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003785 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003786 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003787 return false;
3788 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003789 if (DEBUG_FOCUS) {
3790 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3791 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3792 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003793 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003794 if (DEBUG_FOCUS) {
3795 ALOGD("Cannot transfer focus because windows are on different displays.");
3796 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003797 return false;
3798 }
3799
3800 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003801 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3802 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3803 for (size_t i = 0; i < state.windows.size(); i++) {
3804 const TouchedWindow& touchedWindow = state.windows[i];
3805 if (touchedWindow.windowHandle == fromWindowHandle) {
3806 int32_t oldTargetFlags = touchedWindow.targetFlags;
3807 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003808
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003809 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003810
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003811 int32_t newTargetFlags = oldTargetFlags &
3812 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
3813 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003814 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003815
Jeff Brownf086ddb2014-02-11 14:28:48 -08003816 found = true;
3817 goto Found;
3818 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003819 }
3820 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003821 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003822
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003823 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003824 if (DEBUG_FOCUS) {
3825 ALOGD("Focus transfer failed because from window did not have focus.");
3826 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003827 return false;
3828 }
3829
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07003830 sp<Connection> fromConnection = getConnectionLocked(fromToken);
3831 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003832 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003833 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003834 CancelationOptions
3835 options(CancelationOptions::CANCEL_POINTER_EVENTS,
3836 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003837 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003838 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003839 }
3840
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003841 if (DEBUG_FOCUS) {
3842 logDispatchStateLocked();
3843 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003844 } // release lock
3845
3846 // Wake up poll loop since it may need to make new input dispatching choices.
3847 mLooper->wake();
3848 return true;
3849}
3850
3851void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003852 if (DEBUG_FOCUS) {
3853 ALOGD("Resetting and dropping all events (%s).", reason);
3854 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003855
3856 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3857 synthesizeCancelationEventsForAllConnectionsLocked(options);
3858
3859 resetKeyRepeatLocked();
3860 releasePendingEventLocked();
3861 drainInboundQueueLocked();
3862 resetANRTimeoutsLocked();
3863
Jeff Brownf086ddb2014-02-11 14:28:48 -08003864 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003866 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003867}
3868
3869void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003870 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003871 dumpDispatchStateLocked(dump);
3872
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003873 std::istringstream stream(dump);
3874 std::string line;
3875
3876 while (std::getline(stream, line, '\n')) {
3877 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003878 }
3879}
3880
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003881void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003882 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3883 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3884 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003885 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003886
Tiger Huang721e26f2018-07-24 22:26:19 +08003887 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3888 dump += StringPrintf(INDENT "FocusedApplications:\n");
3889 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3890 const int32_t displayId = it.first;
3891 const sp<InputApplicationHandle>& applicationHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003892 dump += StringPrintf(INDENT2 "displayId=%" PRId32
3893 ", name='%s', dispatchingTimeout=%0.3fms\n",
3894 displayId, applicationHandle->getName().c_str(),
3895 applicationHandle->getDispatchingTimeout(
3896 DEFAULT_INPUT_DISPATCHING_TIMEOUT) /
3897 1000000.0);
Tiger Huang721e26f2018-07-24 22:26:19 +08003898 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003899 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003900 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003901 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003902
3903 if (!mFocusedWindowHandlesByDisplay.empty()) {
3904 dump += StringPrintf(INDENT "FocusedWindows:\n");
3905 for (auto& it : mFocusedWindowHandlesByDisplay) {
3906 const int32_t displayId = it.first;
3907 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003908 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
3909 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003910 }
3911 } else {
3912 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3913 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003914
Jeff Brownf086ddb2014-02-11 14:28:48 -08003915 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003916 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003917 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3918 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003919 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003920 state.displayId, toString(state.down), toString(state.split),
3921 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003922 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003923 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003924 for (size_t i = 0; i < state.windows.size(); i++) {
3925 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003926 dump += StringPrintf(INDENT4
3927 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3928 i, touchedWindow.windowHandle->getName().c_str(),
3929 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003930 }
3931 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003932 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003933 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003934 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003935 dump += INDENT3 "Portal windows:\n";
3936 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003937 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003938 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
3939 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003940 }
3941 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003942 }
3943 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003944 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003945 }
3946
Arthur Hungb92218b2018-08-14 12:00:21 +08003947 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003948 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003949 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003950 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003951 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003952 dump += INDENT2 "Windows:\n";
3953 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003954 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003955 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003956
Arthur Hungb92218b2018-08-14 12:00:21 +08003957 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003958 "portalToDisplayId=%d, paused=%s, hasFocus=%s, "
chaviwcb923212019-12-30 14:05:11 -08003959 "hasWallpaper=%s, visible=%s, canReceiveKeys=%s, "
3960 "flags=0x%08x, type=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003961 "frame=[%d,%d][%d,%d], globalScale=%f, "
chaviwcb923212019-12-30 14:05:11 -08003962 "windowScale=(%f,%f), touchableRegion=",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003963 i, windowInfo->name.c_str(), windowInfo->displayId,
3964 windowInfo->portalToDisplayId,
3965 toString(windowInfo->paused),
3966 toString(windowInfo->hasFocus),
3967 toString(windowInfo->hasWallpaper),
3968 toString(windowInfo->visible),
3969 toString(windowInfo->canReceiveKeys),
3970 windowInfo->layoutParamsFlags,
chaviwcb923212019-12-30 14:05:11 -08003971 windowInfo->layoutParamsType, windowInfo->frameLeft,
3972 windowInfo->frameTop, windowInfo->frameRight,
3973 windowInfo->frameBottom, windowInfo->globalScaleFactor,
3974 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003975 dumpRegion(dump, windowInfo->touchableRegion);
3976 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3977 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003978 windowInfo->ownerPid, windowInfo->ownerUid,
3979 windowInfo->dispatchingTimeout / 1000000.0);
Arthur Hungb92218b2018-08-14 12:00:21 +08003980 }
3981 } else {
3982 dump += INDENT2 "Windows: <none>\n";
3983 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003984 }
3985 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003986 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003987 }
3988
Michael Wright3dd60e22019-03-27 22:06:44 +00003989 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003990 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003991 const std::vector<Monitor>& monitors = it.second;
3992 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3993 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003994 }
3995 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003996 const std::vector<Monitor>& monitors = it.second;
3997 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
3998 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003999 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004000 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004001 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004002 }
4003
4004 nsecs_t currentTime = now();
4005
4006 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004007 if (!mRecentQueue.empty()) {
4008 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
4009 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004010 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004011 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004012 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004013 }
4014 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004015 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004016 }
4017
4018 // Dump event currently being dispatched.
4019 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004020 dump += INDENT "PendingEvent:\n";
4021 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004022 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004023 dump += StringPrintf(", age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004024 (currentTime - mPendingEvent->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004025 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004026 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004027 }
4028
4029 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004030 if (!mInboundQueue.empty()) {
4031 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
4032 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004033 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004034 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004035 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004036 }
4037 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004038 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004039 }
4040
Michael Wright78f24442014-08-06 15:55:28 -07004041 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004042 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07004043 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
4044 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
4045 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004046 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n", i,
4047 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004048 }
4049 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004050 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004051 }
4052
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004053 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004054 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004055 for (const auto& pair : mConnectionsByFd) {
4056 const sp<Connection>& connection = pair.second;
4057 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
4058 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
4059 pair.first, connection->getInputChannelName().c_str(),
4060 connection->getWindowName().c_str(), connection->getStatusLabel(),
4061 toString(connection->monitor),
4062 toString(connection->inputPublisherBlocked));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004063
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004064 if (!connection->outboundQueue.empty()) {
4065 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4066 connection->outboundQueue.size());
4067 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004068 dump.append(INDENT4);
4069 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004070 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004071 entry->targetFlags, entry->resolvedAction,
4072 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004073 }
4074 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004075 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004076 }
4077
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004078 if (!connection->waitQueue.empty()) {
4079 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4080 connection->waitQueue.size());
4081 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004082 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004083 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004084 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004085 "age=%0.1fms, wait=%0.1fms\n",
4086 entry->targetFlags, entry->resolvedAction,
4087 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
4088 (currentTime - entry->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004089 }
4090 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004091 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004092 }
4093 }
4094 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004095 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004096 }
4097
4098 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004099 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004100 (mAppSwitchDueTime - now()) / 1000000.0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004101 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004102 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004103 }
4104
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004105 dump += INDENT "Configuration:\n";
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004106 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004107 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004108 mConfig.keyRepeatTimeout * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004109}
4110
Michael Wright3dd60e22019-03-27 22:06:44 +00004111void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4112 const size_t numMonitors = monitors.size();
4113 for (size_t i = 0; i < numMonitors; i++) {
4114 const Monitor& monitor = monitors[i];
4115 const sp<InputChannel>& channel = monitor.inputChannel;
4116 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4117 dump += "\n";
4118 }
4119}
4120
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004121status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004122#if DEBUG_REGISTRATION
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004123 ALOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004124#endif
4125
4126 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004127 std::scoped_lock _l(mLock);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004128 sp<Connection> existingConnection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004129 if (existingConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004130 ALOGW("Attempted to register already registered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004131 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004132 return BAD_VALUE;
4133 }
4134
Michael Wright3dd60e22019-03-27 22:06:44 +00004135 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004136
4137 int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004138 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004139 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004140
Michael Wrightd02c5b62014-02-10 15:10:22 -08004141 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4142 } // release lock
4143
4144 // Wake the looper because some connections have changed.
4145 mLooper->wake();
4146 return OK;
4147}
4148
Michael Wright3dd60e22019-03-27 22:06:44 +00004149status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004150 int32_t displayId, bool isGestureMonitor) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004151 { // acquire lock
4152 std::scoped_lock _l(mLock);
4153
4154 if (displayId < 0) {
4155 ALOGW("Attempted to register input monitor without a specified display.");
4156 return BAD_VALUE;
4157 }
4158
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004159 if (inputChannel->getConnectionToken() == nullptr) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004160 ALOGW("Attempted to register input monitor without an identifying token.");
4161 return BAD_VALUE;
4162 }
4163
4164 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
4165
4166 const int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004167 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004168 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004169
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004170 auto& monitorsByDisplay =
4171 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Michael Wright3dd60e22019-03-27 22:06:44 +00004172 monitorsByDisplay[displayId].emplace_back(inputChannel);
4173
4174 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004175 }
4176 // Wake the looper because some connections have changed.
4177 mLooper->wake();
4178 return OK;
4179}
4180
Michael Wrightd02c5b62014-02-10 15:10:22 -08004181status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
4182#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004183 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004184#endif
4185
4186 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004187 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004188
4189 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
4190 if (status) {
4191 return status;
4192 }
4193 } // release lock
4194
4195 // Wake the poll loop because removing the connection may have changed the current
4196 // synchronization state.
4197 mLooper->wake();
4198 return OK;
4199}
4200
4201status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004202 bool notify) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004203 sp<Connection> connection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004204 if (connection == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004205 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004206 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004207 return BAD_VALUE;
4208 }
4209
John Recke0710582019-09-26 13:46:12 -07004210 [[maybe_unused]] const bool removed = removeByValue(mConnectionsByFd, connection);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004211 ALOG_ASSERT(removed);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004212 mInputChannelsByToken.erase(inputChannel->getConnectionToken());
Robert Carr5c8a0262018-10-03 16:30:44 -07004213
Michael Wrightd02c5b62014-02-10 15:10:22 -08004214 if (connection->monitor) {
4215 removeMonitorChannelLocked(inputChannel);
4216 }
4217
4218 mLooper->removeFd(inputChannel->getFd());
4219
4220 nsecs_t currentTime = now();
4221 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4222
4223 connection->status = Connection::STATUS_ZOMBIE;
4224 return OK;
4225}
4226
4227void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004228 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4229 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4230}
4231
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004232void InputDispatcher::removeMonitorChannelLocked(
4233 const sp<InputChannel>& inputChannel,
Michael Wright3dd60e22019-03-27 22:06:44 +00004234 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004235 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004236 std::vector<Monitor>& monitors = it->second;
4237 const size_t numMonitors = monitors.size();
4238 for (size_t i = 0; i < numMonitors; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004239 if (monitors[i].inputChannel == inputChannel) {
4240 monitors.erase(monitors.begin() + i);
4241 break;
4242 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004243 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004244 if (monitors.empty()) {
4245 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004246 } else {
4247 ++it;
4248 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004249 }
4250}
4251
Michael Wright3dd60e22019-03-27 22:06:44 +00004252status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4253 { // acquire lock
4254 std::scoped_lock _l(mLock);
4255 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4256
4257 if (!foundDisplayId) {
4258 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4259 return BAD_VALUE;
4260 }
4261 int32_t displayId = foundDisplayId.value();
4262
4263 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4264 if (stateIndex < 0) {
4265 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4266 return BAD_VALUE;
4267 }
4268
4269 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4270 std::optional<int32_t> foundDeviceId;
4271 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004272 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004273 foundDeviceId = state.deviceId;
4274 }
4275 }
4276 if (!foundDeviceId || !state.down) {
4277 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004278 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004279 return BAD_VALUE;
4280 }
4281 int32_t deviceId = foundDeviceId.value();
4282
4283 // Send cancel events to all the input channels we're stealing from.
4284 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004285 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004286 options.deviceId = deviceId;
4287 options.displayId = displayId;
4288 for (const TouchedWindow& window : state.windows) {
4289 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004290 if (channel != nullptr) {
4291 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4292 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004293 }
4294 // Then clear the current touch state so we stop dispatching to them as well.
4295 state.filterNonMonitors();
4296 }
4297 return OK;
4298}
4299
Michael Wright3dd60e22019-03-27 22:06:44 +00004300std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4301 const sp<IBinder>& token) {
4302 for (const auto& it : mGestureMonitorsByDisplay) {
4303 const std::vector<Monitor>& monitors = it.second;
4304 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004305 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004306 return it.first;
4307 }
4308 }
4309 }
4310 return std::nullopt;
4311}
4312
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004313sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) {
4314 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004315 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004316 }
4317
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004318 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004319 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004320 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004321 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004322 }
4323 }
Robert Carr4e670e52018-08-15 13:26:12 -07004324
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004325 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004326}
4327
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004328void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4329 const sp<Connection>& connection, uint32_t seq,
4330 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004331 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4332 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004333 commandEntry->connection = connection;
4334 commandEntry->eventTime = currentTime;
4335 commandEntry->seq = seq;
4336 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004337 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004338}
4339
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004340void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4341 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004342 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004343 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004344
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004345 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4346 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004347 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004348 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004349}
4350
chaviw0c06c6e2019-01-09 13:27:07 -08004351void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004352 const sp<InputWindowHandle>& newFocus) {
chaviw0c06c6e2019-01-09 13:27:07 -08004353 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4354 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004355 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4356 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004357 commandEntry->oldToken = oldToken;
4358 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004359 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004360}
4361
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004362void InputDispatcher::onANRLocked(nsecs_t currentTime,
4363 const sp<InputApplicationHandle>& applicationHandle,
4364 const sp<InputWindowHandle>& windowHandle, nsecs_t eventTime,
4365 nsecs_t waitStartTime, const char* reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004366 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4367 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4368 ALOGI("Application is not responding: %s. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004369 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
4370 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), dispatchLatency,
4371 waitDuration, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004372
4373 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004374 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004375 struct tm tm;
4376 localtime_r(&t, &tm);
4377 char timestr[64];
4378 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4379 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004380 mLastANRState += INDENT "ANR:\n";
4381 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004382 mLastANRState +=
4383 StringPrintf(INDENT2 "Window: %s\n",
4384 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004385 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4386 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4387 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004388 dumpDispatchStateLocked(mLastANRState);
4389
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004390 std::unique_ptr<CommandEntry> commandEntry =
4391 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004392 commandEntry->inputApplicationHandle = applicationHandle;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004393 commandEntry->inputChannel =
4394 windowHandle != nullptr ? getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004395 commandEntry->reason = reason;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004396 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004397}
4398
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004399void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004400 mLock.unlock();
4401
4402 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4403
4404 mLock.lock();
4405}
4406
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004407void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004408 sp<Connection> connection = commandEntry->connection;
4409
4410 if (connection->status != Connection::STATUS_ZOMBIE) {
4411 mLock.unlock();
4412
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004413 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004414
4415 mLock.lock();
4416 }
4417}
4418
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004419void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004420 sp<IBinder> oldToken = commandEntry->oldToken;
4421 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004422 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004423 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004424 mLock.lock();
4425}
4426
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004427void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004428 sp<IBinder> token =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004429 commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004430 mLock.unlock();
4431
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004432 nsecs_t newTimeout =
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004433 mPolicy->notifyANR(commandEntry->inputApplicationHandle, token, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004434
4435 mLock.lock();
4436
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004437 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004438}
4439
4440void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4441 CommandEntry* commandEntry) {
4442 KeyEntry* entry = commandEntry->keyEntry;
4443
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004444 KeyEvent event = createKeyEvent(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004445
4446 mLock.unlock();
4447
Michael Wright2b3c3302018-03-02 17:19:13 +00004448 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004449 sp<IBinder> token = commandEntry->inputChannel != nullptr
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004450 ? commandEntry->inputChannel->getConnectionToken()
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004451 : nullptr;
4452 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004453 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4454 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004455 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004456 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004457
4458 mLock.lock();
4459
4460 if (delay < 0) {
4461 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4462 } else if (!delay) {
4463 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4464 } else {
4465 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4466 entry->interceptKeyWakeupTime = now() + delay;
4467 }
4468 entry->release();
4469}
4470
chaviwfd6d3512019-03-25 13:23:49 -07004471void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4472 mLock.unlock();
4473 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4474 mLock.lock();
4475}
4476
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004477void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004478 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004479 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004480 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004481 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004482
4483 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07004484 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004485 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004486 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004487 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004488 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004489
4490 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4491 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4492 std::string msg =
4493 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4494 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4495 dispatchEntry->eventEntry->appendDescription(msg);
4496 ALOGI("%s", msg.c_str());
4497 }
4498
4499 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004500 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004501 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4502 restartEvent =
4503 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004504 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004505 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4506 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4507 handled);
4508 } else {
4509 restartEvent = false;
4510 }
4511
4512 // Dequeue the event and start the next cycle.
4513 // Note that because the lock might have been released, it is possible that the
4514 // contents of the wait queue to have been drained, so we need to double-check
4515 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004516 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4517 if (dispatchEntryIt != connection->waitQueue.end()) {
4518 dispatchEntry = *dispatchEntryIt;
4519 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004520 traceWaitQueueLength(connection);
4521 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004522 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004523 traceOutboundQueueLength(connection);
4524 } else {
4525 releaseDispatchEntry(dispatchEntry);
4526 }
4527 }
4528
4529 // Start the next dispatch cycle for this connection.
4530 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004531}
4532
4533bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004534 DispatchEntry* dispatchEntry,
4535 KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004536 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004537 if (!handled) {
4538 // Report the key as unhandled, since the fallback was not handled.
4539 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4540 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004541 return false;
4542 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004543
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004544 // Get the fallback key state.
4545 // Clear it out after dispatching the UP.
4546 int32_t originalKeyCode = keyEntry->keyCode;
4547 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4548 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4549 connection->inputState.removeFallbackKey(originalKeyCode);
4550 }
4551
4552 if (handled || !dispatchEntry->hasForegroundTarget()) {
4553 // If the application handles the original key for which we previously
4554 // generated a fallback or if the window is not a foreground window,
4555 // then cancel the associated fallback key, if any.
4556 if (fallbackKeyCode != -1) {
4557 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004558#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004559 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004560 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4561 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4562 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004563#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004564 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004565 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004566
4567 mLock.unlock();
4568
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004569 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004570 keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004571
4572 mLock.lock();
4573
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004574 // Cancel the fallback key.
4575 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004576 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004577 "application handled the original non-fallback key "
4578 "or is no longer a foreground target, "
4579 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004580 options.keyCode = fallbackKeyCode;
4581 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004582 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004583 connection->inputState.removeFallbackKey(originalKeyCode);
4584 }
4585 } else {
4586 // If the application did not handle a non-fallback key, first check
4587 // that we are in a good state to perform unhandled key event processing
4588 // Then ask the policy what to do with it.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004589 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN && keyEntry->repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004590 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004591#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004592 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004593 "since this is not an initial down. "
4594 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4595 originalKeyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004596#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004597 return false;
4598 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004599
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004600 // Dispatch the unhandled key to the policy.
4601#if DEBUG_OUTBOUND_EVENT_DETAILS
4602 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004603 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4604 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004605#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004606 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004607
4608 mLock.unlock();
4609
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004610 bool fallback =
4611 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
4612 &event, keyEntry->policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004613
4614 mLock.lock();
4615
4616 if (connection->status != Connection::STATUS_NORMAL) {
4617 connection->inputState.removeFallbackKey(originalKeyCode);
4618 return false;
4619 }
4620
4621 // Latch the fallback keycode for this key on an initial down.
4622 // The fallback keycode cannot change at any other point in the lifecycle.
4623 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004624 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004625 fallbackKeyCode = event.getKeyCode();
4626 } else {
4627 fallbackKeyCode = AKEYCODE_UNKNOWN;
4628 }
4629 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4630 }
4631
4632 ALOG_ASSERT(fallbackKeyCode != -1);
4633
4634 // Cancel the fallback key if the policy decides not to send it anymore.
4635 // We will continue to dispatch the key to the policy but we will no
4636 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004637 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
4638 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004639#if DEBUG_OUTBOUND_EVENT_DETAILS
4640 if (fallback) {
4641 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004642 "as a fallback for %d, but on the DOWN it had requested "
4643 "to send %d instead. Fallback canceled.",
4644 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004645 } else {
4646 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004647 "but on the DOWN it had requested to send %d. "
4648 "Fallback canceled.",
4649 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004650 }
4651#endif
4652
4653 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4654 "canceling fallback, policy no longer desires it");
4655 options.keyCode = fallbackKeyCode;
4656 synthesizeCancelationEventsForConnectionLocked(connection, options);
4657
4658 fallback = false;
4659 fallbackKeyCode = AKEYCODE_UNKNOWN;
4660 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004661 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004662 }
4663 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004664
4665#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004666 {
4667 std::string msg;
4668 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4669 connection->inputState.getFallbackKeys();
4670 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004671 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004672 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004673 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004674 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004675 }
4676#endif
4677
4678 if (fallback) {
4679 // Restart the dispatch cycle using the fallback key.
4680 keyEntry->eventTime = event.getEventTime();
4681 keyEntry->deviceId = event.getDeviceId();
4682 keyEntry->source = event.getSource();
4683 keyEntry->displayId = event.getDisplayId();
4684 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4685 keyEntry->keyCode = fallbackKeyCode;
4686 keyEntry->scanCode = event.getScanCode();
4687 keyEntry->metaState = event.getMetaState();
4688 keyEntry->repeatCount = event.getRepeatCount();
4689 keyEntry->downTime = event.getDownTime();
4690 keyEntry->syntheticRepeat = false;
4691
4692#if DEBUG_OUTBOUND_EVENT_DETAILS
4693 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004694 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4695 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004696#endif
4697 return true; // restart the event
4698 } else {
4699#if DEBUG_OUTBOUND_EVENT_DETAILS
4700 ALOGD("Unhandled key event: No fallback key.");
4701#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004702
4703 // Report the key as unhandled, since there is no fallback key.
4704 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004705 }
4706 }
4707 return false;
4708}
4709
4710bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004711 DispatchEntry* dispatchEntry,
4712 MotionEntry* motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004713 return false;
4714}
4715
4716void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4717 mLock.unlock();
4718
4719 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4720
4721 mLock.lock();
4722}
4723
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004724KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
4725 KeyEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06004726 event.initialize(entry.deviceId, entry.source, entry.displayId, INVALID_HMAC, entry.action,
4727 entry.flags, entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount,
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004728 entry.downTime, entry.eventTime);
4729 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004730}
4731
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004732void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004733 int32_t injectionResult,
4734 nsecs_t timeSpentWaitingForApplication) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004735 // TODO Write some statistics about how long we spend waiting.
4736}
4737
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05004738/**
4739 * Report the touch event latency to the statsd server.
4740 * Input events are reported for statistics if:
4741 * - This is a touchscreen event
4742 * - InputFilter is not enabled
4743 * - Event is not injected or synthesized
4744 *
4745 * Statistics should be reported before calling addValue, to prevent a fresh new sample
4746 * from getting aggregated with the "old" data.
4747 */
4748void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
4749 REQUIRES(mLock) {
4750 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
4751 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
4752 if (!reportForStatistics) {
4753 return;
4754 }
4755
4756 if (mTouchStatistics.shouldReport()) {
4757 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
4758 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
4759 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
4760 mTouchStatistics.reset();
4761 }
4762 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
4763 mTouchStatistics.addValue(latencyMicros);
4764}
4765
Michael Wrightd02c5b62014-02-10 15:10:22 -08004766void InputDispatcher::traceInboundQueueLengthLocked() {
4767 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004768 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004769 }
4770}
4771
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004772void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004773 if (ATRACE_ENABLED()) {
4774 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004775 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004776 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004777 }
4778}
4779
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004780void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004781 if (ATRACE_ENABLED()) {
4782 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004783 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004784 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004785 }
4786}
4787
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004788void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004789 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004790
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004791 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004792 dumpDispatchStateLocked(dump);
4793
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004794 if (!mLastANRState.empty()) {
4795 dump += "\nInput Dispatcher State at time of last ANR:\n";
4796 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004797 }
4798}
4799
4800void InputDispatcher::monitor() {
4801 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004802 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004803 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004804 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004805}
4806
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08004807/**
4808 * Wake up the dispatcher and wait until it processes all events and commands.
4809 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
4810 * this method can be safely called from any thread, as long as you've ensured that
4811 * the work you are interested in completing has already been queued.
4812 */
4813bool InputDispatcher::waitForIdle() {
4814 /**
4815 * Timeout should represent the longest possible time that a device might spend processing
4816 * events and commands.
4817 */
4818 constexpr std::chrono::duration TIMEOUT = 100ms;
4819 std::unique_lock lock(mLock);
4820 mLooper->wake();
4821 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
4822 return result == std::cv_status::no_timeout;
4823}
4824
Garfield Tane84e6f92019-08-29 17:28:41 -07004825} // namespace android::inputdispatcher