blob: a8158ba3cff2eae79e429bd9ff144dbf6c93e467 [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
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003343std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
3344 return nullptr;
3345}
3346
Michael Wrightd02c5b62014-02-10 15:10:22 -08003347bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003348 return injectorUid == 0 ||
3349 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003350}
3351
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003352void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003353 InjectionState* injectionState = entry->injectionState;
3354 if (injectionState) {
3355#if DEBUG_INJECTION
3356 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003357 "injectorPid=%d, injectorUid=%d",
3358 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003359#endif
3360
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003361 if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003362 // Log the outcome since the injector did not wait for the injection result.
3363 switch (injectionResult) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003364 case INPUT_EVENT_INJECTION_SUCCEEDED:
3365 ALOGV("Asynchronous input event injection succeeded.");
3366 break;
3367 case INPUT_EVENT_INJECTION_FAILED:
3368 ALOGW("Asynchronous input event injection failed.");
3369 break;
3370 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3371 ALOGW("Asynchronous input event injection permission denied.");
3372 break;
3373 case INPUT_EVENT_INJECTION_TIMED_OUT:
3374 ALOGW("Asynchronous input event injection timed out.");
3375 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003376 }
3377 }
3378
3379 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003380 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003381 }
3382}
3383
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003384void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003385 InjectionState* injectionState = entry->injectionState;
3386 if (injectionState) {
3387 injectionState->pendingForegroundDispatches += 1;
3388 }
3389}
3390
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003391void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003392 InjectionState* injectionState = entry->injectionState;
3393 if (injectionState) {
3394 injectionState->pendingForegroundDispatches -= 1;
3395
3396 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003397 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003398 }
3399 }
3400}
3401
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003402std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3403 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003404 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003405}
3406
Michael Wrightd02c5b62014-02-10 15:10:22 -08003407sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003408 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003409 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003410 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3411 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003412 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003413 return windowHandle;
3414 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003415 }
3416 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003417 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003418}
3419
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003420bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003421 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003422 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3423 for (const sp<InputWindowHandle>& handle : windowHandles) {
3424 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003425 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003426 ALOGE("Found window %s in display %" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003427 ", but it should belong to display %" PRId32,
3428 windowHandle->getName().c_str(), it.first,
3429 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003430 }
3431 return true;
3432 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003433 }
3434 }
3435 return false;
3436}
3437
Robert Carr5c8a0262018-10-03 16:30:44 -07003438sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3439 size_t count = mInputChannelsByToken.count(token);
3440 if (count == 0) {
3441 return nullptr;
3442 }
3443 return mInputChannelsByToken.at(token);
3444}
3445
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003446void InputDispatcher::updateWindowHandlesForDisplayLocked(
3447 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3448 if (inputWindowHandles.empty()) {
3449 // Remove all handles on a display if there are no windows left.
3450 mWindowHandlesByDisplay.erase(displayId);
3451 return;
3452 }
3453
3454 // Since we compare the pointer of input window handles across window updates, we need
3455 // to make sure the handle object for the same window stays unchanged across updates.
3456 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003457 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003458 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003459 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003460 }
3461
3462 std::vector<sp<InputWindowHandle>> newHandles;
3463 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3464 if (!handle->updateInfo()) {
3465 // handle no longer valid
3466 continue;
3467 }
3468
3469 const InputWindowInfo* info = handle->getInfo();
3470 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3471 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3472 const bool noInputChannel =
3473 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3474 const bool canReceiveInput =
3475 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3476 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3477 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003478 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003479 handle->getName().c_str());
3480 }
3481 continue;
3482 }
3483
3484 if (info->displayId != displayId) {
3485 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3486 handle->getName().c_str(), displayId, info->displayId);
3487 continue;
3488 }
3489
chaviwaf87b3e2019-10-01 16:59:28 -07003490 if (oldHandlesById.find(handle->getId()) != oldHandlesById.end()) {
3491 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003492 oldHandle->updateFrom(handle);
3493 newHandles.push_back(oldHandle);
3494 } else {
3495 newHandles.push_back(handle);
3496 }
3497 }
3498
3499 // Insert or replace
3500 mWindowHandlesByDisplay[displayId] = newHandles;
3501}
3502
Arthur Hungb92218b2018-08-14 12:00:21 +08003503/**
3504 * Called from InputManagerService, update window handle list by displayId that can receive input.
3505 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3506 * If set an empty list, remove all handles from the specific display.
3507 * For focused handle, check if need to change and send a cancel event to previous one.
3508 * For removed handle, check if need to send a cancel event if already in touch.
3509 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003510void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003511 int32_t displayId,
3512 const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003513 if (DEBUG_FOCUS) {
3514 std::string windowList;
3515 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
3516 windowList += iwh->getName() + " ";
3517 }
3518 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
3519 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003520 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003521 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003522
Arthur Hungb92218b2018-08-14 12:00:21 +08003523 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003524 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3525 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003526
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003527 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3528
Tiger Huang721e26f2018-07-24 22:26:19 +08003529 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003530 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003531 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3532 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3533 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3534 windowHandle->getInfo()->visible) {
3535 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003536 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003537 if (windowHandle == mLastHoverWindowHandle) {
3538 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003539 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003540 }
3541
3542 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003543 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003544 }
3545
Tiger Huang721e26f2018-07-24 22:26:19 +08003546 sp<InputWindowHandle> oldFocusedWindowHandle =
3547 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3548
chaviwaf87b3e2019-10-01 16:59:28 -07003549 if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003550 if (oldFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003551 if (DEBUG_FOCUS) {
3552 ALOGD("Focus left window: %s in display %" PRId32,
3553 oldFocusedWindowHandle->getName().c_str(), displayId);
3554 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003555 sp<InputChannel> focusedInputChannel =
3556 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003557 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003558 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003559 "focus left window");
3560 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003561 enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003562 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003563 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003564 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003565 if (newFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003566 if (DEBUG_FOCUS) {
3567 ALOGD("Focus entered window: %s in display %" PRId32,
3568 newFocusedWindowHandle->getName().c_str(), displayId);
3569 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003570 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003571 enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003572 }
Robert Carrf759f162018-11-13 12:57:11 -08003573
3574 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003575 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003576 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003577 }
3578
Arthur Hungb92218b2018-08-14 12:00:21 +08003579 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3580 if (stateIndex >= 0) {
3581 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003582 for (size_t i = 0; i < state.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003583 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003584 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003585 if (DEBUG_FOCUS) {
3586 ALOGD("Touched window was removed: %s in display %" PRId32,
3587 touchedWindow.windowHandle->getName().c_str(), displayId);
3588 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003589 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003590 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003591 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003592 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003593 "touched window was removed");
3594 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
3595 options);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003596 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003597 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003598 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003599 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003600 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003601 }
3602 }
3603
3604 // Release information for windows that are no longer present.
3605 // This ensures that unused input channels are released promptly.
3606 // Otherwise, they might stick around until the window handle is destroyed
3607 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003608 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003609 if (!hasWindowHandleLocked(oldWindowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003610 if (DEBUG_FOCUS) {
3611 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
3612 }
Arthur Hung3b413f22018-10-26 18:05:34 +08003613 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003614 }
3615 }
3616 } // release lock
3617
3618 // Wake up poll loop since it may need to make new input dispatching choices.
3619 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003620
3621 if (setInputWindowsListener) {
3622 setInputWindowsListener->onSetInputWindowsFinished();
3623 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003624}
3625
3626void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003627 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003628 if (DEBUG_FOCUS) {
3629 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
3630 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
3631 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003632 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003633 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003634
Tiger Huang721e26f2018-07-24 22:26:19 +08003635 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3636 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003637 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003638 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3639 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003640 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003641 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003642 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003643 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003644 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003645 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003646 oldFocusedApplicationHandle.clear();
3647 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003648 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003649 } // release lock
3650
3651 // Wake up poll loop since it may need to make new input dispatching choices.
3652 mLooper->wake();
3653}
3654
Tiger Huang721e26f2018-07-24 22:26:19 +08003655/**
3656 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3657 * the display not specified.
3658 *
3659 * We track any unreleased events for each window. If a window loses the ability to receive the
3660 * released event, we will send a cancel event to it. So when the focused display is changed, we
3661 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3662 * display. The display-specified events won't be affected.
3663 */
3664void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003665 if (DEBUG_FOCUS) {
3666 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3667 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003668 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003669 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003670
3671 if (mFocusedDisplayId != displayId) {
3672 sp<InputWindowHandle> oldFocusedWindowHandle =
3673 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3674 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003675 sp<InputChannel> inputChannel =
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003676 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003677 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003678 CancelationOptions
3679 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3680 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003681 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003682 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3683 }
3684 }
3685 mFocusedDisplayId = displayId;
3686
3687 // Sanity check
3688 sp<InputWindowHandle> newFocusedWindowHandle =
3689 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003690 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003691
Tiger Huang721e26f2018-07-24 22:26:19 +08003692 if (newFocusedWindowHandle == nullptr) {
3693 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3694 if (!mFocusedWindowHandlesByDisplay.empty()) {
3695 ALOGE("But another display has a focused window:");
3696 for (auto& it : mFocusedWindowHandlesByDisplay) {
3697 const int32_t displayId = it.first;
3698 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003699 ALOGE("Display #%" PRId32 " has focused window: '%s'\n", displayId,
3700 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003701 }
3702 }
3703 }
3704 }
3705
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003706 if (DEBUG_FOCUS) {
3707 logDispatchStateLocked();
3708 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003709 } // release lock
3710
3711 // Wake up poll loop since it may need to make new input dispatching choices.
3712 mLooper->wake();
3713}
3714
Michael Wrightd02c5b62014-02-10 15:10:22 -08003715void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003716 if (DEBUG_FOCUS) {
3717 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3718 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003719
3720 bool changed;
3721 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003722 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003723
3724 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3725 if (mDispatchFrozen && !frozen) {
3726 resetANRTimeoutsLocked();
3727 }
3728
3729 if (mDispatchEnabled && !enabled) {
3730 resetAndDropEverythingLocked("dispatcher is being disabled");
3731 }
3732
3733 mDispatchEnabled = enabled;
3734 mDispatchFrozen = frozen;
3735 changed = true;
3736 } else {
3737 changed = false;
3738 }
3739
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003740 if (DEBUG_FOCUS) {
3741 logDispatchStateLocked();
3742 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003743 } // release lock
3744
3745 if (changed) {
3746 // Wake up poll loop since it may need to make new input dispatching choices.
3747 mLooper->wake();
3748 }
3749}
3750
3751void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003752 if (DEBUG_FOCUS) {
3753 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3754 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003755
3756 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003757 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003758
3759 if (mInputFilterEnabled == enabled) {
3760 return;
3761 }
3762
3763 mInputFilterEnabled = enabled;
3764 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3765 } // release lock
3766
3767 // Wake up poll loop since there might be work to do to drop everything.
3768 mLooper->wake();
3769}
3770
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08003771void InputDispatcher::setInTouchMode(bool inTouchMode) {
3772 std::scoped_lock lock(mLock);
3773 mInTouchMode = inTouchMode;
3774}
3775
chaviwfbe5d9c2018-12-26 12:23:37 -08003776bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3777 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003778 if (DEBUG_FOCUS) {
3779 ALOGD("Trivial transfer to same window.");
3780 }
chaviwfbe5d9c2018-12-26 12:23:37 -08003781 return true;
3782 }
3783
Michael Wrightd02c5b62014-02-10 15:10:22 -08003784 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003785 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003786
chaviwfbe5d9c2018-12-26 12:23:37 -08003787 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3788 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003789 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003790 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003791 return false;
3792 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003793 if (DEBUG_FOCUS) {
3794 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3795 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3796 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003797 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003798 if (DEBUG_FOCUS) {
3799 ALOGD("Cannot transfer focus because windows are on different displays.");
3800 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003801 return false;
3802 }
3803
3804 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003805 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3806 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3807 for (size_t i = 0; i < state.windows.size(); i++) {
3808 const TouchedWindow& touchedWindow = state.windows[i];
3809 if (touchedWindow.windowHandle == fromWindowHandle) {
3810 int32_t oldTargetFlags = touchedWindow.targetFlags;
3811 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003812
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003813 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003814
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003815 int32_t newTargetFlags = oldTargetFlags &
3816 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
3817 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003818 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003819
Jeff Brownf086ddb2014-02-11 14:28:48 -08003820 found = true;
3821 goto Found;
3822 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003823 }
3824 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003825 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003826
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003827 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003828 if (DEBUG_FOCUS) {
3829 ALOGD("Focus transfer failed because from window did not have focus.");
3830 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003831 return false;
3832 }
3833
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07003834 sp<Connection> fromConnection = getConnectionLocked(fromToken);
3835 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003836 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003837 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003838 CancelationOptions
3839 options(CancelationOptions::CANCEL_POINTER_EVENTS,
3840 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003841 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003842 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003843 }
3844
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003845 if (DEBUG_FOCUS) {
3846 logDispatchStateLocked();
3847 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848 } // release lock
3849
3850 // Wake up poll loop since it may need to make new input dispatching choices.
3851 mLooper->wake();
3852 return true;
3853}
3854
3855void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003856 if (DEBUG_FOCUS) {
3857 ALOGD("Resetting and dropping all events (%s).", reason);
3858 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003859
3860 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3861 synthesizeCancelationEventsForAllConnectionsLocked(options);
3862
3863 resetKeyRepeatLocked();
3864 releasePendingEventLocked();
3865 drainInboundQueueLocked();
3866 resetANRTimeoutsLocked();
3867
Jeff Brownf086ddb2014-02-11 14:28:48 -08003868 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003869 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003870 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003871}
3872
3873void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003874 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003875 dumpDispatchStateLocked(dump);
3876
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003877 std::istringstream stream(dump);
3878 std::string line;
3879
3880 while (std::getline(stream, line, '\n')) {
3881 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003882 }
3883}
3884
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003885void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003886 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3887 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3888 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003889 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003890
Tiger Huang721e26f2018-07-24 22:26:19 +08003891 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3892 dump += StringPrintf(INDENT "FocusedApplications:\n");
3893 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3894 const int32_t displayId = it.first;
3895 const sp<InputApplicationHandle>& applicationHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003896 dump += StringPrintf(INDENT2 "displayId=%" PRId32
3897 ", name='%s', dispatchingTimeout=%0.3fms\n",
3898 displayId, applicationHandle->getName().c_str(),
3899 applicationHandle->getDispatchingTimeout(
3900 DEFAULT_INPUT_DISPATCHING_TIMEOUT) /
3901 1000000.0);
Tiger Huang721e26f2018-07-24 22:26:19 +08003902 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003903 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003904 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003905 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003906
3907 if (!mFocusedWindowHandlesByDisplay.empty()) {
3908 dump += StringPrintf(INDENT "FocusedWindows:\n");
3909 for (auto& it : mFocusedWindowHandlesByDisplay) {
3910 const int32_t displayId = it.first;
3911 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003912 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
3913 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003914 }
3915 } else {
3916 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3917 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003918
Jeff Brownf086ddb2014-02-11 14:28:48 -08003919 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003920 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003921 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3922 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003923 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003924 state.displayId, toString(state.down), toString(state.split),
3925 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003926 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003927 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003928 for (size_t i = 0; i < state.windows.size(); i++) {
3929 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003930 dump += StringPrintf(INDENT4
3931 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3932 i, touchedWindow.windowHandle->getName().c_str(),
3933 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003934 }
3935 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003936 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003937 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003938 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003939 dump += INDENT3 "Portal windows:\n";
3940 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003941 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003942 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
3943 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003944 }
3945 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003946 }
3947 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003948 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003949 }
3950
Arthur Hungb92218b2018-08-14 12:00:21 +08003951 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003952 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003953 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003954 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003955 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003956 dump += INDENT2 "Windows:\n";
3957 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003958 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003959 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003960
Arthur Hungb92218b2018-08-14 12:00:21 +08003961 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003962 "portalToDisplayId=%d, paused=%s, hasFocus=%s, "
chaviwcb923212019-12-30 14:05:11 -08003963 "hasWallpaper=%s, visible=%s, canReceiveKeys=%s, "
3964 "flags=0x%08x, type=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003965 "frame=[%d,%d][%d,%d], globalScale=%f, "
chaviwcb923212019-12-30 14:05:11 -08003966 "windowScale=(%f,%f), touchableRegion=",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003967 i, windowInfo->name.c_str(), windowInfo->displayId,
3968 windowInfo->portalToDisplayId,
3969 toString(windowInfo->paused),
3970 toString(windowInfo->hasFocus),
3971 toString(windowInfo->hasWallpaper),
3972 toString(windowInfo->visible),
3973 toString(windowInfo->canReceiveKeys),
3974 windowInfo->layoutParamsFlags,
chaviwcb923212019-12-30 14:05:11 -08003975 windowInfo->layoutParamsType, windowInfo->frameLeft,
3976 windowInfo->frameTop, windowInfo->frameRight,
3977 windowInfo->frameBottom, windowInfo->globalScaleFactor,
3978 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003979 dumpRegion(dump, windowInfo->touchableRegion);
3980 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3981 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003982 windowInfo->ownerPid, windowInfo->ownerUid,
3983 windowInfo->dispatchingTimeout / 1000000.0);
Arthur Hungb92218b2018-08-14 12:00:21 +08003984 }
3985 } else {
3986 dump += INDENT2 "Windows: <none>\n";
3987 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003988 }
3989 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003990 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003991 }
3992
Michael Wright3dd60e22019-03-27 22:06:44 +00003993 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003994 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003995 const std::vector<Monitor>& monitors = it.second;
3996 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3997 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003998 }
3999 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004000 const std::vector<Monitor>& monitors = it.second;
4001 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4002 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004003 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004004 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004005 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004006 }
4007
4008 nsecs_t currentTime = now();
4009
4010 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004011 if (!mRecentQueue.empty()) {
4012 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
4013 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004014 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004015 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004016 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004017 }
4018 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004019 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004020 }
4021
4022 // Dump event currently being dispatched.
4023 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004024 dump += INDENT "PendingEvent:\n";
4025 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004026 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004027 dump += StringPrintf(", age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004028 (currentTime - mPendingEvent->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004029 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004030 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004031 }
4032
4033 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004034 if (!mInboundQueue.empty()) {
4035 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
4036 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004037 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004038 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004039 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004040 }
4041 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004042 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004043 }
4044
Michael Wright78f24442014-08-06 15:55:28 -07004045 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004046 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07004047 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
4048 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
4049 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004050 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n", i,
4051 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004052 }
4053 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004054 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004055 }
4056
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004057 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004058 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004059 for (const auto& pair : mConnectionsByFd) {
4060 const sp<Connection>& connection = pair.second;
4061 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
4062 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
4063 pair.first, connection->getInputChannelName().c_str(),
4064 connection->getWindowName().c_str(), connection->getStatusLabel(),
4065 toString(connection->monitor),
4066 toString(connection->inputPublisherBlocked));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004067
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004068 if (!connection->outboundQueue.empty()) {
4069 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4070 connection->outboundQueue.size());
4071 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004072 dump.append(INDENT4);
4073 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004074 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004075 entry->targetFlags, entry->resolvedAction,
4076 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004077 }
4078 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004079 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004080 }
4081
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004082 if (!connection->waitQueue.empty()) {
4083 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4084 connection->waitQueue.size());
4085 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004086 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004087 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004088 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004089 "age=%0.1fms, wait=%0.1fms\n",
4090 entry->targetFlags, entry->resolvedAction,
4091 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
4092 (currentTime - entry->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004093 }
4094 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004095 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004096 }
4097 }
4098 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004099 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004100 }
4101
4102 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004103 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004104 (mAppSwitchDueTime - now()) / 1000000.0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004105 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004106 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004107 }
4108
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004109 dump += INDENT "Configuration:\n";
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004110 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004111 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004112 mConfig.keyRepeatTimeout * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004113}
4114
Michael Wright3dd60e22019-03-27 22:06:44 +00004115void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4116 const size_t numMonitors = monitors.size();
4117 for (size_t i = 0; i < numMonitors; i++) {
4118 const Monitor& monitor = monitors[i];
4119 const sp<InputChannel>& channel = monitor.inputChannel;
4120 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4121 dump += "\n";
4122 }
4123}
4124
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004125status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004126#if DEBUG_REGISTRATION
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004127 ALOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004128#endif
4129
4130 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004131 std::scoped_lock _l(mLock);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004132 sp<Connection> existingConnection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004133 if (existingConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004134 ALOGW("Attempted to register already registered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004135 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004136 return BAD_VALUE;
4137 }
4138
Michael Wright3dd60e22019-03-27 22:06:44 +00004139 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004140
4141 int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004142 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004143 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004144
Michael Wrightd02c5b62014-02-10 15:10:22 -08004145 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4146 } // release lock
4147
4148 // Wake the looper because some connections have changed.
4149 mLooper->wake();
4150 return OK;
4151}
4152
Michael Wright3dd60e22019-03-27 22:06:44 +00004153status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004154 int32_t displayId, bool isGestureMonitor) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004155 { // acquire lock
4156 std::scoped_lock _l(mLock);
4157
4158 if (displayId < 0) {
4159 ALOGW("Attempted to register input monitor without a specified display.");
4160 return BAD_VALUE;
4161 }
4162
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004163 if (inputChannel->getConnectionToken() == nullptr) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004164 ALOGW("Attempted to register input monitor without an identifying token.");
4165 return BAD_VALUE;
4166 }
4167
4168 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
4169
4170 const int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004171 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004172 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004173
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004174 auto& monitorsByDisplay =
4175 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Michael Wright3dd60e22019-03-27 22:06:44 +00004176 monitorsByDisplay[displayId].emplace_back(inputChannel);
4177
4178 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004179 }
4180 // Wake the looper because some connections have changed.
4181 mLooper->wake();
4182 return OK;
4183}
4184
Michael Wrightd02c5b62014-02-10 15:10:22 -08004185status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
4186#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004187 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004188#endif
4189
4190 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004191 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004192
4193 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
4194 if (status) {
4195 return status;
4196 }
4197 } // release lock
4198
4199 // Wake the poll loop because removing the connection may have changed the current
4200 // synchronization state.
4201 mLooper->wake();
4202 return OK;
4203}
4204
4205status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004206 bool notify) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004207 sp<Connection> connection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004208 if (connection == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004209 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004210 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004211 return BAD_VALUE;
4212 }
4213
John Recke0710582019-09-26 13:46:12 -07004214 [[maybe_unused]] const bool removed = removeByValue(mConnectionsByFd, connection);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004215 ALOG_ASSERT(removed);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004216 mInputChannelsByToken.erase(inputChannel->getConnectionToken());
Robert Carr5c8a0262018-10-03 16:30:44 -07004217
Michael Wrightd02c5b62014-02-10 15:10:22 -08004218 if (connection->monitor) {
4219 removeMonitorChannelLocked(inputChannel);
4220 }
4221
4222 mLooper->removeFd(inputChannel->getFd());
4223
4224 nsecs_t currentTime = now();
4225 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4226
4227 connection->status = Connection::STATUS_ZOMBIE;
4228 return OK;
4229}
4230
4231void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004232 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4233 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4234}
4235
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004236void InputDispatcher::removeMonitorChannelLocked(
4237 const sp<InputChannel>& inputChannel,
Michael Wright3dd60e22019-03-27 22:06:44 +00004238 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004239 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004240 std::vector<Monitor>& monitors = it->second;
4241 const size_t numMonitors = monitors.size();
4242 for (size_t i = 0; i < numMonitors; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004243 if (monitors[i].inputChannel == inputChannel) {
4244 monitors.erase(monitors.begin() + i);
4245 break;
4246 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004247 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004248 if (monitors.empty()) {
4249 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004250 } else {
4251 ++it;
4252 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004253 }
4254}
4255
Michael Wright3dd60e22019-03-27 22:06:44 +00004256status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4257 { // acquire lock
4258 std::scoped_lock _l(mLock);
4259 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4260
4261 if (!foundDisplayId) {
4262 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4263 return BAD_VALUE;
4264 }
4265 int32_t displayId = foundDisplayId.value();
4266
4267 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4268 if (stateIndex < 0) {
4269 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4270 return BAD_VALUE;
4271 }
4272
4273 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4274 std::optional<int32_t> foundDeviceId;
4275 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004276 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004277 foundDeviceId = state.deviceId;
4278 }
4279 }
4280 if (!foundDeviceId || !state.down) {
4281 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004282 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004283 return BAD_VALUE;
4284 }
4285 int32_t deviceId = foundDeviceId.value();
4286
4287 // Send cancel events to all the input channels we're stealing from.
4288 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004289 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004290 options.deviceId = deviceId;
4291 options.displayId = displayId;
4292 for (const TouchedWindow& window : state.windows) {
4293 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004294 if (channel != nullptr) {
4295 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4296 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004297 }
4298 // Then clear the current touch state so we stop dispatching to them as well.
4299 state.filterNonMonitors();
4300 }
4301 return OK;
4302}
4303
Michael Wright3dd60e22019-03-27 22:06:44 +00004304std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4305 const sp<IBinder>& token) {
4306 for (const auto& it : mGestureMonitorsByDisplay) {
4307 const std::vector<Monitor>& monitors = it.second;
4308 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004309 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004310 return it.first;
4311 }
4312 }
4313 }
4314 return std::nullopt;
4315}
4316
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004317sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) {
4318 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004319 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004320 }
4321
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004322 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004323 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004324 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004325 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004326 }
4327 }
Robert Carr4e670e52018-08-15 13:26:12 -07004328
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004329 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004330}
4331
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004332void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4333 const sp<Connection>& connection, uint32_t seq,
4334 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004335 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4336 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004337 commandEntry->connection = connection;
4338 commandEntry->eventTime = currentTime;
4339 commandEntry->seq = seq;
4340 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004341 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004342}
4343
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004344void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4345 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004346 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004347 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004348
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004349 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4350 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004351 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004352 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004353}
4354
chaviw0c06c6e2019-01-09 13:27:07 -08004355void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004356 const sp<InputWindowHandle>& newFocus) {
chaviw0c06c6e2019-01-09 13:27:07 -08004357 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4358 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004359 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4360 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004361 commandEntry->oldToken = oldToken;
4362 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004363 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004364}
4365
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004366void InputDispatcher::onANRLocked(nsecs_t currentTime,
4367 const sp<InputApplicationHandle>& applicationHandle,
4368 const sp<InputWindowHandle>& windowHandle, nsecs_t eventTime,
4369 nsecs_t waitStartTime, const char* reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004370 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4371 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4372 ALOGI("Application is not responding: %s. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004373 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
4374 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), dispatchLatency,
4375 waitDuration, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004376
4377 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004378 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004379 struct tm tm;
4380 localtime_r(&t, &tm);
4381 char timestr[64];
4382 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4383 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004384 mLastANRState += INDENT "ANR:\n";
4385 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004386 mLastANRState +=
4387 StringPrintf(INDENT2 "Window: %s\n",
4388 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004389 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4390 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4391 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004392 dumpDispatchStateLocked(mLastANRState);
4393
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004394 std::unique_ptr<CommandEntry> commandEntry =
4395 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004396 commandEntry->inputApplicationHandle = applicationHandle;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004397 commandEntry->inputChannel =
4398 windowHandle != nullptr ? getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004399 commandEntry->reason = reason;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004400 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004401}
4402
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004403void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004404 mLock.unlock();
4405
4406 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4407
4408 mLock.lock();
4409}
4410
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004411void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004412 sp<Connection> connection = commandEntry->connection;
4413
4414 if (connection->status != Connection::STATUS_ZOMBIE) {
4415 mLock.unlock();
4416
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004417 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004418
4419 mLock.lock();
4420 }
4421}
4422
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004423void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004424 sp<IBinder> oldToken = commandEntry->oldToken;
4425 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004426 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004427 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004428 mLock.lock();
4429}
4430
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004431void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004432 sp<IBinder> token =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004433 commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004434 mLock.unlock();
4435
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004436 nsecs_t newTimeout =
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004437 mPolicy->notifyANR(commandEntry->inputApplicationHandle, token, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004438
4439 mLock.lock();
4440
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004441 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004442}
4443
4444void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4445 CommandEntry* commandEntry) {
4446 KeyEntry* entry = commandEntry->keyEntry;
4447
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004448 KeyEvent event = createKeyEvent(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004449
4450 mLock.unlock();
4451
Michael Wright2b3c3302018-03-02 17:19:13 +00004452 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004453 sp<IBinder> token = commandEntry->inputChannel != nullptr
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004454 ? commandEntry->inputChannel->getConnectionToken()
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004455 : nullptr;
4456 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004457 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4458 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004459 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004460 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004461
4462 mLock.lock();
4463
4464 if (delay < 0) {
4465 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4466 } else if (!delay) {
4467 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4468 } else {
4469 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4470 entry->interceptKeyWakeupTime = now() + delay;
4471 }
4472 entry->release();
4473}
4474
chaviwfd6d3512019-03-25 13:23:49 -07004475void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4476 mLock.unlock();
4477 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4478 mLock.lock();
4479}
4480
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004481void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004482 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004483 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004484 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004485 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004486
4487 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07004488 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004489 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004490 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004491 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004492 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004493
4494 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4495 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4496 std::string msg =
4497 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4498 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4499 dispatchEntry->eventEntry->appendDescription(msg);
4500 ALOGI("%s", msg.c_str());
4501 }
4502
4503 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004504 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004505 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4506 restartEvent =
4507 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004508 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004509 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4510 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4511 handled);
4512 } else {
4513 restartEvent = false;
4514 }
4515
4516 // Dequeue the event and start the next cycle.
4517 // Note that because the lock might have been released, it is possible that the
4518 // contents of the wait queue to have been drained, so we need to double-check
4519 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004520 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4521 if (dispatchEntryIt != connection->waitQueue.end()) {
4522 dispatchEntry = *dispatchEntryIt;
4523 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004524 traceWaitQueueLength(connection);
4525 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004526 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004527 traceOutboundQueueLength(connection);
4528 } else {
4529 releaseDispatchEntry(dispatchEntry);
4530 }
4531 }
4532
4533 // Start the next dispatch cycle for this connection.
4534 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004535}
4536
4537bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004538 DispatchEntry* dispatchEntry,
4539 KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004540 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004541 if (!handled) {
4542 // Report the key as unhandled, since the fallback was not handled.
4543 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4544 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004545 return false;
4546 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004547
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004548 // Get the fallback key state.
4549 // Clear it out after dispatching the UP.
4550 int32_t originalKeyCode = keyEntry->keyCode;
4551 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4552 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4553 connection->inputState.removeFallbackKey(originalKeyCode);
4554 }
4555
4556 if (handled || !dispatchEntry->hasForegroundTarget()) {
4557 // If the application handles the original key for which we previously
4558 // generated a fallback or if the window is not a foreground window,
4559 // then cancel the associated fallback key, if any.
4560 if (fallbackKeyCode != -1) {
4561 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004562#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004563 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004564 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4565 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4566 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004567#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004568 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004569 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004570
4571 mLock.unlock();
4572
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004573 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004574 keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004575
4576 mLock.lock();
4577
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004578 // Cancel the fallback key.
4579 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004580 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004581 "application handled the original non-fallback key "
4582 "or is no longer a foreground target, "
4583 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004584 options.keyCode = fallbackKeyCode;
4585 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004586 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004587 connection->inputState.removeFallbackKey(originalKeyCode);
4588 }
4589 } else {
4590 // If the application did not handle a non-fallback key, first check
4591 // that we are in a good state to perform unhandled key event processing
4592 // Then ask the policy what to do with it.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004593 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN && keyEntry->repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004594 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004595#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004596 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004597 "since this is not an initial down. "
4598 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4599 originalKeyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004600#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004601 return false;
4602 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004603
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004604 // Dispatch the unhandled key to the policy.
4605#if DEBUG_OUTBOUND_EVENT_DETAILS
4606 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004607 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4608 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004609#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004610 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004611
4612 mLock.unlock();
4613
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004614 bool fallback =
4615 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
4616 &event, keyEntry->policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004617
4618 mLock.lock();
4619
4620 if (connection->status != Connection::STATUS_NORMAL) {
4621 connection->inputState.removeFallbackKey(originalKeyCode);
4622 return false;
4623 }
4624
4625 // Latch the fallback keycode for this key on an initial down.
4626 // The fallback keycode cannot change at any other point in the lifecycle.
4627 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004628 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004629 fallbackKeyCode = event.getKeyCode();
4630 } else {
4631 fallbackKeyCode = AKEYCODE_UNKNOWN;
4632 }
4633 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4634 }
4635
4636 ALOG_ASSERT(fallbackKeyCode != -1);
4637
4638 // Cancel the fallback key if the policy decides not to send it anymore.
4639 // We will continue to dispatch the key to the policy but we will no
4640 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004641 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
4642 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004643#if DEBUG_OUTBOUND_EVENT_DETAILS
4644 if (fallback) {
4645 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004646 "as a fallback for %d, but on the DOWN it had requested "
4647 "to send %d instead. Fallback canceled.",
4648 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004649 } else {
4650 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004651 "but on the DOWN it had requested to send %d. "
4652 "Fallback canceled.",
4653 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004654 }
4655#endif
4656
4657 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4658 "canceling fallback, policy no longer desires it");
4659 options.keyCode = fallbackKeyCode;
4660 synthesizeCancelationEventsForConnectionLocked(connection, options);
4661
4662 fallback = false;
4663 fallbackKeyCode = AKEYCODE_UNKNOWN;
4664 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004665 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004666 }
4667 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004668
4669#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004670 {
4671 std::string msg;
4672 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4673 connection->inputState.getFallbackKeys();
4674 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004675 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004676 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004677 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004678 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004679 }
4680#endif
4681
4682 if (fallback) {
4683 // Restart the dispatch cycle using the fallback key.
4684 keyEntry->eventTime = event.getEventTime();
4685 keyEntry->deviceId = event.getDeviceId();
4686 keyEntry->source = event.getSource();
4687 keyEntry->displayId = event.getDisplayId();
4688 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4689 keyEntry->keyCode = fallbackKeyCode;
4690 keyEntry->scanCode = event.getScanCode();
4691 keyEntry->metaState = event.getMetaState();
4692 keyEntry->repeatCount = event.getRepeatCount();
4693 keyEntry->downTime = event.getDownTime();
4694 keyEntry->syntheticRepeat = false;
4695
4696#if DEBUG_OUTBOUND_EVENT_DETAILS
4697 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004698 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4699 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004700#endif
4701 return true; // restart the event
4702 } else {
4703#if DEBUG_OUTBOUND_EVENT_DETAILS
4704 ALOGD("Unhandled key event: No fallback key.");
4705#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004706
4707 // Report the key as unhandled, since there is no fallback key.
4708 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004709 }
4710 }
4711 return false;
4712}
4713
4714bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004715 DispatchEntry* dispatchEntry,
4716 MotionEntry* motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004717 return false;
4718}
4719
4720void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4721 mLock.unlock();
4722
4723 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4724
4725 mLock.lock();
4726}
4727
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004728KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
4729 KeyEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06004730 event.initialize(entry.deviceId, entry.source, entry.displayId, INVALID_HMAC, entry.action,
4731 entry.flags, entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount,
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004732 entry.downTime, entry.eventTime);
4733 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004734}
4735
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004736void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004737 int32_t injectionResult,
4738 nsecs_t timeSpentWaitingForApplication) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004739 // TODO Write some statistics about how long we spend waiting.
4740}
4741
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05004742/**
4743 * Report the touch event latency to the statsd server.
4744 * Input events are reported for statistics if:
4745 * - This is a touchscreen event
4746 * - InputFilter is not enabled
4747 * - Event is not injected or synthesized
4748 *
4749 * Statistics should be reported before calling addValue, to prevent a fresh new sample
4750 * from getting aggregated with the "old" data.
4751 */
4752void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
4753 REQUIRES(mLock) {
4754 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
4755 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
4756 if (!reportForStatistics) {
4757 return;
4758 }
4759
4760 if (mTouchStatistics.shouldReport()) {
4761 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
4762 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
4763 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
4764 mTouchStatistics.reset();
4765 }
4766 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
4767 mTouchStatistics.addValue(latencyMicros);
4768}
4769
Michael Wrightd02c5b62014-02-10 15:10:22 -08004770void InputDispatcher::traceInboundQueueLengthLocked() {
4771 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004772 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004773 }
4774}
4775
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004776void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004777 if (ATRACE_ENABLED()) {
4778 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004779 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004780 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004781 }
4782}
4783
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004784void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004785 if (ATRACE_ENABLED()) {
4786 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004787 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004788 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004789 }
4790}
4791
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004792void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004793 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004794
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004795 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004796 dumpDispatchStateLocked(dump);
4797
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004798 if (!mLastANRState.empty()) {
4799 dump += "\nInput Dispatcher State at time of last ANR:\n";
4800 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004801 }
4802}
4803
4804void InputDispatcher::monitor() {
4805 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004806 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004807 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004808 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004809}
4810
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08004811/**
4812 * Wake up the dispatcher and wait until it processes all events and commands.
4813 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
4814 * this method can be safely called from any thread, as long as you've ensured that
4815 * the work you are interested in completing has already been queued.
4816 */
4817bool InputDispatcher::waitForIdle() {
4818 /**
4819 * Timeout should represent the longest possible time that a device might spend processing
4820 * events and commands.
4821 */
4822 constexpr std::chrono::duration TIMEOUT = 100ms;
4823 std::unique_lock lock(mLock);
4824 mLooper->wake();
4825 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
4826 return result == std::cv_status::no_timeout;
4827}
4828
Garfield Tane84e6f92019-08-29 17:28:41 -07004829} // namespace android::inputdispatcher