blob: 6157d997fd65316af891cd3c5bbb689937d7996c [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 Weingarten97b8eec2020-01-09 18:09:08 +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[MAX_POINTERS];
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 return std::make_unique<DispatchEntry>(combinedMotionEntry, // increments ref
314 inputTargetFlags, firstPointerInfo.xOffset,
315 firstPointerInfo.yOffset, inputTarget.globalScaleFactor,
316 firstPointerInfo.windowXScale,
317 firstPointerInfo.windowYScale);
318}
319
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700320// --- InputDispatcherThread ---
321
322class InputDispatcher::InputDispatcherThread : public Thread {
323public:
324 explicit InputDispatcherThread(InputDispatcher* dispatcher)
325 : Thread(/* canCallJava */ true), mDispatcher(dispatcher) {}
326
327 ~InputDispatcherThread() {}
328
329private:
330 InputDispatcher* mDispatcher;
331
332 virtual bool threadLoop() override {
333 mDispatcher->dispatchOnce();
334 return true;
335 }
336};
337
Michael Wrightd02c5b62014-02-10 15:10:22 -0800338// --- InputDispatcher ---
339
Garfield Tan00f511d2019-06-12 16:55:40 -0700340InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
341 : mPolicy(policy),
342 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700343 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tan00f511d2019-06-12 16:55:40 -0700344 mAppSwitchSawKeyDown(false),
345 mAppSwitchDueTime(LONG_LONG_MAX),
346 mNextUnblockedEvent(nullptr),
347 mDispatchEnabled(false),
348 mDispatchFrozen(false),
349 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800350 // mInTouchMode will be initialized by the WindowManager to the default device config.
351 // To avoid leaking stack in case that call never comes, and for tests,
352 // initialize it here anyways.
353 mInTouchMode(true),
Garfield Tan00f511d2019-06-12 16:55:40 -0700354 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
355 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800356 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800357 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800358
Yi Kong9b14ac62018-07-17 13:48:38 -0700359 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800360
361 policy->getDispatcherConfiguration(&mConfig);
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700362
363 mThread = new InputDispatcherThread(this);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800364}
365
366InputDispatcher::~InputDispatcher() {
367 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800368 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800369
370 resetKeyRepeatLocked();
371 releasePendingEventLocked();
372 drainInboundQueueLocked();
373 }
374
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700375 while (!mConnectionsByFd.empty()) {
376 sp<Connection> connection = mConnectionsByFd.begin()->second;
377 unregisterInputChannel(connection->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800378 }
379}
380
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700381status_t InputDispatcher::start() {
382 if (mThread->isRunning()) {
383 return ALREADY_EXISTS;
384 }
385 return mThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
386}
387
388status_t InputDispatcher::stop() {
389 if (!mThread->isRunning()) {
390 return OK;
391 }
392 if (gettid() == mThread->getTid()) {
393 ALOGE("InputDispatcher can only be stopped from outside of the InputDispatcherThread!");
394 return INVALID_OPERATION;
395 }
396 // Directly calling requestExitAndWait() causes the thread to not exit
397 // if mLooper is waiting for a long timeout.
398 mThread->requestExit();
399 mLooper->wake();
400 return mThread->requestExitAndWait();
401}
402
Michael Wrightd02c5b62014-02-10 15:10:22 -0800403void InputDispatcher::dispatchOnce() {
404 nsecs_t nextWakeupTime = LONG_LONG_MAX;
405 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800406 std::scoped_lock _l(mLock);
407 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800408
409 // Run a dispatch loop if there are no pending commands.
410 // The dispatch loop might enqueue commands to run afterwards.
411 if (!haveCommandsLocked()) {
412 dispatchOnceInnerLocked(&nextWakeupTime);
413 }
414
415 // Run all pending commands if there are any.
416 // If any commands were run then force the next poll to wake up immediately.
417 if (runCommandsLockedInterruptible()) {
418 nextWakeupTime = LONG_LONG_MIN;
419 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800420
421 // We are about to enter an infinitely long sleep, because we have no commands or
422 // pending or queued events
423 if (nextWakeupTime == LONG_LONG_MAX) {
424 mDispatcherEnteredIdle.notify_all();
425 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800426 } // release lock
427
428 // Wait for callback or timeout or wake. (make sure we round up, not down)
429 nsecs_t currentTime = now();
430 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
431 mLooper->pollOnce(timeoutMillis);
432}
433
434void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
435 nsecs_t currentTime = now();
436
Jeff Browndc5992e2014-04-11 01:27:26 -0700437 // Reset the key repeat timer whenever normal dispatch is suspended while the
438 // device is in a non-interactive state. This is to ensure that we abort a key
439 // repeat if the device is just coming out of sleep.
440 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800441 resetKeyRepeatLocked();
442 }
443
444 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
445 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100446 if (DEBUG_FOCUS) {
447 ALOGD("Dispatch frozen. Waiting some more.");
448 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800449 return;
450 }
451
452 // Optimize latency of app switches.
453 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
454 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
455 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
456 if (mAppSwitchDueTime < *nextWakeupTime) {
457 *nextWakeupTime = mAppSwitchDueTime;
458 }
459
460 // Ready to start a new event.
461 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700462 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700463 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800464 if (isAppSwitchDue) {
465 // The inbound queue is empty so the app switch key we were waiting
466 // for will never arrive. Stop waiting for it.
467 resetPendingAppSwitchLocked(false);
468 isAppSwitchDue = false;
469 }
470
471 // Synthesize a key repeat if appropriate.
472 if (mKeyRepeatState.lastKeyEntry) {
473 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
474 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
475 } else {
476 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
477 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
478 }
479 }
480 }
481
482 // Nothing to do if there is no pending event.
483 if (!mPendingEvent) {
484 return;
485 }
486 } else {
487 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700488 mPendingEvent = mInboundQueue.front();
489 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800490 traceInboundQueueLengthLocked();
491 }
492
493 // Poke user activity for this event.
494 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700495 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800496 }
497
498 // Get ready to dispatch the event.
499 resetANRTimeoutsLocked();
500 }
501
502 // Now we have an event to dispatch.
503 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700504 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800505 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700506 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800507 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700508 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800509 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700510 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800511 }
512
513 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700514 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800515 }
516
517 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700518 case EventEntry::Type::CONFIGURATION_CHANGED: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700519 ConfigurationChangedEntry* typedEntry =
520 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
521 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700522 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700523 break;
524 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800525
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700526 case EventEntry::Type::DEVICE_RESET: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700527 DeviceResetEntry* typedEntry = static_cast<DeviceResetEntry*>(mPendingEvent);
528 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700529 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700530 break;
531 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800532
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700533 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700534 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
535 if (isAppSwitchDue) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700536 if (isAppSwitchKeyEvent(*typedEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700537 resetPendingAppSwitchLocked(true);
538 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700539 } else if (dropReason == DropReason::NOT_DROPPED) {
540 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700541 }
542 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700543 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700544 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700545 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700546 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
547 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700548 }
549 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
550 break;
551 }
552
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700553 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700554 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700555 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
556 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800557 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700558 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700559 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700560 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700561 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
562 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700563 }
564 done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
565 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800566 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800567 }
568
569 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700570 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700571 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800572 }
Michael Wright3a981722015-06-10 15:26:13 +0100573 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800574
575 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700576 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800577 }
578}
579
580bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700581 bool needWake = mInboundQueue.empty();
582 mInboundQueue.push_back(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800583 traceInboundQueueLengthLocked();
584
585 switch (entry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700586 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700587 // Optimize app switch latency.
588 // If the application takes too long to catch up then we drop all events preceding
589 // the app switch key.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700590 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700591 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700592 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700593 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700594 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700595 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800596#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700597 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800598#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700599 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700600 mAppSwitchSawKeyDown = false;
601 needWake = true;
602 }
603 }
604 }
605 break;
606 }
607
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700608 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700609 // Optimize case where the current application is unresponsive and the user
610 // decides to touch a window in a different application.
611 // If the application takes too long to catch up then we drop all events preceding
612 // the touch into the other window.
613 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
614 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN &&
615 (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
616 mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY &&
617 mInputTargetWaitApplicationToken != nullptr) {
618 int32_t displayId = motionEntry->displayId;
619 int32_t x =
620 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
621 int32_t y =
622 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
623 sp<InputWindowHandle> touchedWindowHandle =
624 findTouchedWindowAtLocked(displayId, x, y);
625 if (touchedWindowHandle != nullptr &&
626 touchedWindowHandle->getApplicationToken() !=
627 mInputTargetWaitApplicationToken) {
628 // User touched a different application than the one we are waiting on.
629 // Flag the event, and start pruning the input queue.
630 mNextUnblockedEvent = motionEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800631 needWake = true;
632 }
633 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700634 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800635 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700636 case EventEntry::Type::CONFIGURATION_CHANGED:
637 case EventEntry::Type::DEVICE_RESET: {
638 // nothing to do
639 break;
640 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800641 }
642
643 return needWake;
644}
645
646void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
647 entry->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700648 mRecentQueue.push_back(entry);
649 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
650 mRecentQueue.front()->release();
651 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800652 }
653}
654
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700655sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
656 int32_t y, bool addOutsideTargets,
657 bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800658 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800659 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
660 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800661 const InputWindowInfo* windowInfo = windowHandle->getInfo();
662 if (windowInfo->displayId == displayId) {
663 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800664
665 if (windowInfo->visible) {
666 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700667 bool isTouchModal = (flags &
668 (InputWindowInfo::FLAG_NOT_FOCUSABLE |
669 InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800670 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800671 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700672 if (portalToDisplayId != ADISPLAY_ID_NONE &&
673 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800674 if (addPortalWindows) {
675 // For the monitoring channels of the display.
676 mTempTouchState.addPortalWindow(windowHandle);
677 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700678 return findTouchedWindowAtLocked(portalToDisplayId, x, y,
679 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800680 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800681 // Found window.
682 return windowHandle;
683 }
684 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800685
686 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700687 mTempTouchState.addOrUpdateWindow(windowHandle,
688 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
689 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800690 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800691 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800692 }
693 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700694 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800695}
696
Garfield Tane84e6f92019-08-29 17:28:41 -0700697std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +0000698 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
699 std::vector<TouchedMonitor> touchedMonitors;
700
701 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
702 addGestureMonitors(monitors, touchedMonitors);
703 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
704 const InputWindowInfo* windowInfo = portalWindow->getInfo();
705 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700706 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
707 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000708 }
709 return touchedMonitors;
710}
711
712void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700713 std::vector<TouchedMonitor>& outTouchedMonitors,
714 float xOffset, float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000715 if (monitors.empty()) {
716 return;
717 }
718 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
719 for (const Monitor& monitor : monitors) {
720 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
721 }
722}
723
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700724void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800725 const char* reason;
726 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700727 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800728#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700729 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800730#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700731 reason = "inbound event was dropped because the policy consumed it";
732 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700733 case DropReason::DISABLED:
734 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700735 ALOGI("Dropped event because input dispatch is disabled.");
736 }
737 reason = "inbound event was dropped because input dispatch is disabled";
738 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700739 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700740 ALOGI("Dropped event because of pending overdue app switch.");
741 reason = "inbound event was dropped because of pending overdue app switch";
742 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700743 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700744 ALOGI("Dropped event because the current application is not responding and the user "
745 "has started interacting with a different application.");
746 reason = "inbound event was dropped because the current application is not responding "
747 "and the user has started interacting with a different application";
748 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700749 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700750 ALOGI("Dropped event because it is stale.");
751 reason = "inbound event was dropped because it is stale";
752 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700753 case DropReason::NOT_DROPPED: {
754 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700755 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700756 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800757 }
758
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700759 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700760 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800761 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
762 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700763 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800764 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700765 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700766 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
767 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700768 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
769 synthesizeCancelationEventsForAllConnectionsLocked(options);
770 } else {
771 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
772 synthesizeCancelationEventsForAllConnectionsLocked(options);
773 }
774 break;
775 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700776 case EventEntry::Type::CONFIGURATION_CHANGED:
777 case EventEntry::Type::DEVICE_RESET: {
778 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
779 break;
780 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800781 }
782}
783
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800784static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700785 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
786 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800787}
788
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700789bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
790 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
791 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
792 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800793}
794
795bool InputDispatcher::isAppSwitchPendingLocked() {
796 return mAppSwitchDueTime != LONG_LONG_MAX;
797}
798
799void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
800 mAppSwitchDueTime = LONG_LONG_MAX;
801
802#if DEBUG_APP_SWITCH
803 if (handled) {
804 ALOGD("App switch has arrived.");
805 } else {
806 ALOGD("App switch was abandoned.");
807 }
808#endif
809}
810
Michael Wrightd02c5b62014-02-10 15:10:22 -0800811bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700812 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800813}
814
815bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700816 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800817 return false;
818 }
819
820 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700821 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700822 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800823 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700824 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800825
826 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700827 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800828 return true;
829}
830
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700831void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
832 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800833}
834
835void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700836 while (!mInboundQueue.empty()) {
837 EventEntry* entry = mInboundQueue.front();
838 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800839 releaseInboundEventLocked(entry);
840 }
841 traceInboundQueueLengthLocked();
842}
843
844void InputDispatcher::releasePendingEventLocked() {
845 if (mPendingEvent) {
846 resetANRTimeoutsLocked();
847 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700848 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800849 }
850}
851
852void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
853 InjectionState* injectionState = entry->injectionState;
854 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
855#if DEBUG_DISPATCH_CYCLE
856 ALOGD("Injected inbound event was dropped.");
857#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800858 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800859 }
860 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700861 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800862 }
863 addRecentEventLocked(entry);
864 entry->release();
865}
866
867void InputDispatcher::resetKeyRepeatLocked() {
868 if (mKeyRepeatState.lastKeyEntry) {
869 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700870 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800871 }
872}
873
Garfield Tane84e6f92019-08-29 17:28:41 -0700874KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800875 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
876
877 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700878 uint32_t policyFlags = entry->policyFlags &
879 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800880 if (entry->refCount == 1) {
881 entry->recycle();
882 entry->eventTime = currentTime;
883 entry->policyFlags = policyFlags;
884 entry->repeatCount += 1;
885 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700886 KeyEntry* newEntry =
887 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, entry->deviceId,
888 entry->source, entry->displayId, policyFlags, entry->action,
889 entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
890 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800891
892 mKeyRepeatState.lastKeyEntry = newEntry;
893 entry->release();
894
895 entry = newEntry;
896 }
897 entry->syntheticRepeat = true;
898
899 // Increment reference count since we keep a reference to the event in
900 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
901 entry->refCount += 1;
902
903 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
904 return entry;
905}
906
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700907bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
908 ConfigurationChangedEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800909#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700910 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800911#endif
912
913 // Reset key repeating in case a keyboard device was added or removed or something.
914 resetKeyRepeatLocked();
915
916 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700917 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
918 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800919 commandEntry->eventTime = entry->eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700920 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800921 return true;
922}
923
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700924bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceResetEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800925#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700926 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700927 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800928#endif
929
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700930 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800931 options.deviceId = entry->deviceId;
932 synthesizeCancelationEventsForAllConnectionsLocked(options);
933 return true;
934}
935
936bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700937 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800938 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700939 if (!entry->dispatchInProgress) {
940 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
941 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
942 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
943 if (mKeyRepeatState.lastKeyEntry &&
944 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800945 // We have seen two identical key downs in a row which indicates that the device
946 // driver is automatically generating key repeats itself. We take note of the
947 // repeat here, but we disable our own next key repeat timer since it is clear that
948 // we will not need to synthesize key repeats ourselves.
949 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
950 resetKeyRepeatLocked();
951 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
952 } else {
953 // Not a repeat. Save key down state in case we do see a repeat later.
954 resetKeyRepeatLocked();
955 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
956 }
957 mKeyRepeatState.lastKeyEntry = entry;
958 entry->refCount += 1;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700959 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800960 resetKeyRepeatLocked();
961 }
962
963 if (entry->repeatCount == 1) {
964 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
965 } else {
966 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
967 }
968
969 entry->dispatchInProgress = true;
970
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700971 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800972 }
973
974 // Handle case where the policy asked us to try again later last time.
975 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
976 if (currentTime < entry->interceptKeyWakeupTime) {
977 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
978 *nextWakeupTime = entry->interceptKeyWakeupTime;
979 }
980 return false; // wait until next wakeup
981 }
982 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
983 entry->interceptKeyWakeupTime = 0;
984 }
985
986 // Give the policy a chance to intercept the key.
987 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
988 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700989 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700990 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +0800991 sp<InputWindowHandle> focusedWindowHandle =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700992 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(*entry));
Tiger Huang721e26f2018-07-24 22:26:19 +0800993 if (focusedWindowHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700994 commandEntry->inputChannel = getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800995 }
996 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700997 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800998 entry->refCount += 1;
999 return false; // wait for the command to run
1000 } else {
1001 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1002 }
1003 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001004 if (*dropReason == DropReason::NOT_DROPPED) {
1005 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001006 }
1007 }
1008
1009 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001010 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001011 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001012 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001013 : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08001014 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001015 return true;
1016 }
1017
1018 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001019 std::vector<InputTarget> inputTargets;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001020 int32_t injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001021 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001022 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1023 return false;
1024 }
1025
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001026 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001027 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
1028 return true;
1029 }
1030
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001031 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001032 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001033
1034 // Dispatch the key.
1035 dispatchEventLocked(currentTime, entry, inputTargets);
1036 return true;
1037}
1038
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001039void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001040#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001041 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001042 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1043 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001044 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1045 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1046 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001047#endif
1048}
1049
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001050bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry,
1051 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001052 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001053 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001054 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001055 entry->dispatchInProgress = true;
1056
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001057 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001058 }
1059
1060 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001061 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001062 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001063 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001064 : INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001065 return true;
1066 }
1067
1068 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1069
1070 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001071 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001072
1073 bool conflictingPointerActions = false;
1074 int32_t injectionResult;
1075 if (isPointerEvent) {
1076 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001077 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001078 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001079 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080 } else {
1081 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001082 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001083 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001084 }
1085 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1086 return false;
1087 }
1088
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001089 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001090 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001091 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001092 CancelationOptions::Mode mode(isPointerEvent
1093 ? CancelationOptions::CANCEL_POINTER_EVENTS
1094 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001095 CancelationOptions options(mode, "input event injection failed");
1096 synthesizeCancelationEventsForMonitorsLocked(options);
1097 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001098 return true;
1099 }
1100
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001101 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001102 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001103
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001104 if (isPointerEvent) {
1105 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1106 if (stateIndex >= 0) {
1107 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001108 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001109 // The event has gone through these portal windows, so we add monitoring targets of
1110 // the corresponding displays as well.
1111 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001112 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001113 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001114 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001115 }
1116 }
1117 }
1118 }
1119
Michael Wrightd02c5b62014-02-10 15:10:22 -08001120 // Dispatch the motion.
1121 if (conflictingPointerActions) {
1122 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001123 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001124 synthesizeCancelationEventsForAllConnectionsLocked(options);
1125 }
1126 dispatchEventLocked(currentTime, entry, inputTargets);
1127 return true;
1128}
1129
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001130void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001131#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001132 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001133 ", policyFlags=0x%x, "
1134 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1135 "metaState=0x%x, buttonState=0x%x,"
1136 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001137 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1138 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1139 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001140
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001141 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001142 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001143 "x=%f, y=%f, pressure=%f, size=%f, "
1144 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1145 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001146 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1147 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1148 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1149 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1150 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1151 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1152 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1153 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1154 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1155 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001156 }
1157#endif
1158}
1159
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001160void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* eventEntry,
1161 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001162 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001163#if DEBUG_DISPATCH_CYCLE
1164 ALOGD("dispatchEventToCurrentInputTargets");
1165#endif
1166
1167 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1168
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001169 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001170
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001171 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001172 sp<Connection> connection =
1173 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001174 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001175 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001176 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001177 if (DEBUG_FOCUS) {
1178 ALOGD("Dropping event delivery to target with channel '%s' because it "
1179 "is no longer registered with the input dispatcher.",
1180 inputTarget.inputChannel->getName().c_str());
1181 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001182 }
1183 }
1184}
1185
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001186int32_t InputDispatcher::handleTargetsNotReadyLocked(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001187 nsecs_t currentTime, const EventEntry& entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001188 const sp<InputApplicationHandle>& applicationHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001189 const sp<InputWindowHandle>& windowHandle, nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001190 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001191 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001192 if (DEBUG_FOCUS) {
1193 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1194 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001195 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1196 mInputTargetWaitStartTime = currentTime;
1197 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1198 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001199 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001200 }
1201 } else {
1202 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001203 if (DEBUG_FOCUS) {
1204 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
1205 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), reason);
1206 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001207 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001208 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001209 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001210 } else if (applicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001211 timeout =
1212 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001213 } else {
1214 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1215 }
1216
1217 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1218 mInputTargetWaitStartTime = currentTime;
1219 mInputTargetWaitTimeoutTime = currentTime + timeout;
1220 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001221 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001222
Yi Kong9b14ac62018-07-17 13:48:38 -07001223 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001224 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001225 }
Robert Carr740167f2018-10-11 19:03:41 -07001226 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1227 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001228 }
1229 }
1230 }
1231
1232 if (mInputTargetWaitTimeoutExpired) {
1233 return INPUT_EVENT_INJECTION_TIMED_OUT;
1234 }
1235
1236 if (currentTime >= mInputTargetWaitTimeoutTime) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001237 onANRLocked(currentTime, applicationHandle, windowHandle, entry.eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001238 mInputTargetWaitStartTime, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001239
1240 // Force poll loop to wake up immediately on next iteration once we get the
1241 // ANR response back from the policy.
1242 *nextWakeupTime = LONG_LONG_MIN;
1243 return INPUT_EVENT_INJECTION_PENDING;
1244 } else {
1245 // Force poll loop to wake up when timeout is due.
1246 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1247 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1248 }
1249 return INPUT_EVENT_INJECTION_PENDING;
1250 }
1251}
1252
Robert Carr803535b2018-08-02 16:38:15 -07001253void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1254 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1255 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1256 state.removeWindowByToken(token);
1257 }
1258}
1259
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001260void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001261 nsecs_t newTimeout, const sp<IBinder>& inputConnectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001262 if (newTimeout > 0) {
1263 // Extend the timeout.
1264 mInputTargetWaitTimeoutTime = now() + newTimeout;
1265 } else {
1266 // Give up.
1267 mInputTargetWaitTimeoutExpired = true;
1268
1269 // Input state will not be realistic. Mark it out of sync.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001270 sp<Connection> connection = getConnectionLocked(inputConnectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001271 if (connection != nullptr) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001272 removeWindowByTokenLocked(inputConnectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001273
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001274 if (connection->status == Connection::STATUS_NORMAL) {
1275 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1276 "application not responding");
1277 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001278 }
1279 }
1280 }
1281}
1282
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001283nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001284 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1285 return currentTime - mInputTargetWaitStartTime;
1286 }
1287 return 0;
1288}
1289
1290void InputDispatcher::resetANRTimeoutsLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001291 if (DEBUG_FOCUS) {
1292 ALOGD("Resetting ANR timeouts.");
1293 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001294
1295 // Reset input target wait timeout.
1296 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001297 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001298}
1299
Tiger Huang721e26f2018-07-24 22:26:19 +08001300/**
1301 * Get the display id that the given event should go to. If this event specifies a valid display id,
1302 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1303 * Focused display is the display that the user most recently interacted with.
1304 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001305int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001306 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001307 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001308 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001309 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1310 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001311 break;
1312 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001313 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001314 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1315 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001316 break;
1317 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001318 case EventEntry::Type::CONFIGURATION_CHANGED:
1319 case EventEntry::Type::DEVICE_RESET: {
1320 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001321 return ADISPLAY_ID_NONE;
1322 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001323 }
1324 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1325}
1326
Michael Wrightd02c5b62014-02-10 15:10:22 -08001327int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001328 const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001329 std::vector<InputTarget>& inputTargets,
1330 nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001331 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001332 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001333
Tiger Huang721e26f2018-07-24 22:26:19 +08001334 int32_t displayId = getTargetDisplayId(entry);
1335 sp<InputWindowHandle> focusedWindowHandle =
1336 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1337 sp<InputApplicationHandle> focusedApplicationHandle =
1338 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1339
Michael Wrightd02c5b62014-02-10 15:10:22 -08001340 // If there is no currently focused window and no focused application
1341 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001342 if (focusedWindowHandle == nullptr) {
1343 if (focusedApplicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001344 injectionResult =
1345 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1346 nullptr, nextWakeupTime,
1347 "Waiting because no window has focus but there is "
1348 "a focused application that may eventually add a "
1349 "window when it finishes starting up.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001350 goto Unresponsive;
1351 }
1352
Arthur Hung3b413f22018-10-26 18:05:34 +08001353 ALOGI("Dropping event because there is no focused window or focused application in display "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001354 "%" PRId32 ".",
1355 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001356 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1357 goto Failed;
1358 }
1359
1360 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001361 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001362 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1363 goto Failed;
1364 }
1365
Jeff Brownffb49772014-10-10 19:01:34 -07001366 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001367 reason = checkWindowReadyForMoreInputLocked(currentTime, focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001368 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001369 injectionResult =
1370 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1371 focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001372 goto Unresponsive;
1373 }
1374
1375 // Success! Output targets.
1376 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001377 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001378 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1379 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001380
1381 // Done.
1382Failed:
1383Unresponsive:
1384 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001385 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001386 if (DEBUG_FOCUS) {
1387 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1388 "timeSpentWaitingForApplication=%0.1fms",
1389 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1390 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001391 return injectionResult;
1392}
1393
1394int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001395 const MotionEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001396 std::vector<InputTarget>& inputTargets,
1397 nsecs_t* nextWakeupTime,
1398 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001399 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001400 enum InjectionPermission {
1401 INJECTION_PERMISSION_UNKNOWN,
1402 INJECTION_PERMISSION_GRANTED,
1403 INJECTION_PERMISSION_DENIED
1404 };
1405
Michael Wrightd02c5b62014-02-10 15:10:22 -08001406 // For security reasons, we defer updating the touch state until we are sure that
1407 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001408 int32_t displayId = entry.displayId;
1409 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001410 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1411
1412 // Update the touch state as needed based on the properties of the touch event.
1413 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1414 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1415 sp<InputWindowHandle> newHoverWindowHandle;
1416
Jeff Brownf086ddb2014-02-11 14:28:48 -08001417 // Copy current touch state into mTempTouchState.
1418 // This state is always reset at the end of this function, so if we don't find state
1419 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001420 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001421 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1422 if (oldStateIndex >= 0) {
1423 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1424 mTempTouchState.copyFrom(*oldState);
1425 }
1426
1427 bool isSplit = mTempTouchState.split;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001428 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0 &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001429 (mTempTouchState.deviceId != entry.deviceId || mTempTouchState.source != entry.source ||
1430 mTempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001431 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1432 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1433 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1434 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1435 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001436 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001437 bool wrongDevice = false;
1438 if (newGesture) {
1439 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001440 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001441 if (DEBUG_FOCUS) {
1442 ALOGD("Dropping event because a pointer for a different device is already down "
1443 "in display %" PRId32,
1444 displayId);
1445 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001446 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001447 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1448 switchedDevice = false;
1449 wrongDevice = true;
1450 goto Failed;
1451 }
1452 mTempTouchState.reset();
1453 mTempTouchState.down = down;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001454 mTempTouchState.deviceId = entry.deviceId;
1455 mTempTouchState.source = entry.source;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001456 mTempTouchState.displayId = displayId;
1457 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001458 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001459 if (DEBUG_FOCUS) {
1460 ALOGI("Dropping move event because a pointer for a different device is already active "
1461 "in display %" PRId32,
1462 displayId);
1463 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001464 // TODO: test multiple simultaneous input streams.
1465 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1466 switchedDevice = false;
1467 wrongDevice = true;
1468 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001469 }
1470
1471 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1472 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1473
Garfield Tan00f511d2019-06-12 16:55:40 -07001474 int32_t x;
1475 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001476 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001477 // Always dispatch mouse events to cursor position.
1478 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001479 x = int32_t(entry.xCursorPosition);
1480 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001481 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001482 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1483 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001484 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001485 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001486 sp<InputWindowHandle> newTouchedWindowHandle =
1487 findTouchedWindowAtLocked(displayId, x, y, isDown /*addOutsideTargets*/,
1488 true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001489
1490 std::vector<TouchedMonitor> newGestureMonitors = isDown
1491 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1492 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001493
Michael Wrightd02c5b62014-02-10 15:10:22 -08001494 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001495 if (newTouchedWindowHandle != nullptr &&
1496 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001497 // New window supports splitting, but we should never split mouse events.
1498 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001499 } else if (isSplit) {
1500 // New window does not support splitting but we have already split events.
1501 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001502 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001503 }
1504
1505 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001506 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001507 // Try to assign the pointer to the first foreground window we find, if there is one.
1508 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001509 }
1510
1511 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1512 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001513 "(%d, %d) in display %" PRId32 ".",
1514 x, y, displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00001515 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1516 goto Failed;
1517 }
1518
1519 if (newTouchedWindowHandle != nullptr) {
1520 // Set target flags.
1521 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1522 if (isSplit) {
1523 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001524 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001525 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1526 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1527 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1528 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1529 }
1530
1531 // Update hover state.
1532 if (isHoverAction) {
1533 newHoverWindowHandle = newTouchedWindowHandle;
1534 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1535 newHoverWindowHandle = mLastHoverWindowHandle;
1536 }
1537
1538 // Update the temporary touch state.
1539 BitSet32 pointerIds;
1540 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001541 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001542 pointerIds.markBit(pointerId);
1543 }
1544 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001545 }
1546
Michael Wright3dd60e22019-03-27 22:06:44 +00001547 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001548 } else {
1549 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1550
1551 // If the pointer is not currently down, then ignore the event.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001552 if (!mTempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001553 if (DEBUG_FOCUS) {
1554 ALOGD("Dropping event because the pointer is not down or we previously "
1555 "dropped the pointer down event in display %" PRId32,
1556 displayId);
1557 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001558 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1559 goto Failed;
1560 }
1561
1562 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001563 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001564 mTempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001565 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1566 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001567
1568 sp<InputWindowHandle> oldTouchedWindowHandle =
1569 mTempTouchState.getFirstForegroundWindowHandle();
1570 sp<InputWindowHandle> newTouchedWindowHandle =
1571 findTouchedWindowAtLocked(displayId, x, y);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001572 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1573 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001574 if (DEBUG_FOCUS) {
1575 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1576 oldTouchedWindowHandle->getName().c_str(),
1577 newTouchedWindowHandle->getName().c_str(), displayId);
1578 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001579 // Make a slippery exit from the old window.
1580 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001581 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1582 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001583
1584 // Make a slippery entrance into the new window.
1585 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1586 isSplit = true;
1587 }
1588
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001589 int32_t targetFlags =
1590 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001591 if (isSplit) {
1592 targetFlags |= InputTarget::FLAG_SPLIT;
1593 }
1594 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1595 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1596 }
1597
1598 BitSet32 pointerIds;
1599 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001600 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001601 }
1602 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1603 }
1604 }
1605 }
1606
1607 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1608 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001609 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001610#if DEBUG_HOVER
1611 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001612 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001613#endif
1614 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001615 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT,
1616 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001617 }
1618
1619 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001620 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001621#if DEBUG_HOVER
1622 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001623 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001624#endif
1625 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001626 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1627 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001628 }
1629 }
1630
1631 // Check permission to inject into all touched foreground windows and ensure there
1632 // is at least one touched foreground window.
1633 {
1634 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001635 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001636 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1637 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001638 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001639 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1640 injectionPermission = INJECTION_PERMISSION_DENIED;
1641 goto Failed;
1642 }
1643 }
1644 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001645 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1646 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001647 if (DEBUG_FOCUS) {
1648 ALOGD("Dropping event because there is no touched foreground window in display "
1649 "%" PRId32 " or gesture monitor to receive it.",
1650 displayId);
1651 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001652 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1653 goto Failed;
1654 }
1655
1656 // Permission granted to injection into all touched foreground windows.
1657 injectionPermission = INJECTION_PERMISSION_GRANTED;
1658 }
1659
1660 // Check whether windows listening for outside touches are owned by the same UID. If it is
1661 // set the policy flag that we will not reveal coordinate information to this window.
1662 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1663 sp<InputWindowHandle> foregroundWindowHandle =
1664 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001665 if (foregroundWindowHandle) {
1666 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1667 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1668 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1669 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1670 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1671 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001672 InputTarget::FLAG_ZERO_COORDS,
1673 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001674 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001675 }
1676 }
1677 }
1678 }
1679
1680 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001681 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001682 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001683 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001684 std::string reason =
1685 checkWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle,
1686 entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001687 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001688 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, nullptr,
1689 touchedWindow.windowHandle,
1690 nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001691 goto Unresponsive;
1692 }
1693 }
1694 }
1695
1696 // If this is the first pointer going down and the touched window has a wallpaper
1697 // then also add the touched wallpaper windows so they are locked in for the duration
1698 // of the touch gesture.
1699 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1700 // engine only supports touch events. We would need to add a mechanism similar
1701 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1702 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1703 sp<InputWindowHandle> foregroundWindowHandle =
1704 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001705 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001706 const std::vector<sp<InputWindowHandle>> windowHandles =
1707 getWindowHandlesLocked(displayId);
1708 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001709 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001710 if (info->displayId == displayId &&
1711 windowHandle->getInfo()->layoutParamsType == InputWindowInfo::TYPE_WALLPAPER) {
1712 mTempTouchState
1713 .addOrUpdateWindow(windowHandle,
1714 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1715 InputTarget::
1716 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1717 InputTarget::FLAG_DISPATCH_AS_IS,
1718 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001719 }
1720 }
1721 }
1722 }
1723
1724 // Success! Output targets.
1725 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1726
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001727 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001728 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001729 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001730 }
1731
Michael Wright3dd60e22019-03-27 22:06:44 +00001732 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1733 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001734 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00001735 }
1736
Michael Wrightd02c5b62014-02-10 15:10:22 -08001737 // Drop the outside or hover touch windows since we will not care about them
1738 // in the next iteration.
1739 mTempTouchState.filterNonAsIsTouchWindows();
1740
1741Failed:
1742 // Check injection permission once and for all.
1743 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001744 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001745 injectionPermission = INJECTION_PERMISSION_GRANTED;
1746 } else {
1747 injectionPermission = INJECTION_PERMISSION_DENIED;
1748 }
1749 }
1750
1751 // Update final pieces of touch state if the injector had permission.
1752 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1753 if (!wrongDevice) {
1754 if (switchedDevice) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001755 if (DEBUG_FOCUS) {
1756 ALOGD("Conflicting pointer actions: Switched to a different device.");
1757 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001758 *outConflictingPointerActions = true;
1759 }
1760
1761 if (isHoverAction) {
1762 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001763 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001764 if (DEBUG_FOCUS) {
1765 ALOGD("Conflicting pointer actions: Hover received while pointer was "
1766 "down.");
1767 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001768 *outConflictingPointerActions = true;
1769 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001770 mTempTouchState.reset();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001771 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1772 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001773 mTempTouchState.deviceId = entry.deviceId;
1774 mTempTouchState.source = entry.source;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001775 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001776 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001777 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
1778 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001779 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001780 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001781 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1782 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001783 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001784 if (DEBUG_FOCUS) {
1785 ALOGD("Conflicting pointer actions: Down received while already down.");
1786 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001787 *outConflictingPointerActions = true;
1788 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001789 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1790 // One pointer went up.
1791 if (isSplit) {
1792 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001793 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001794
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001795 for (size_t i = 0; i < mTempTouchState.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001796 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001797 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1798 touchedWindow.pointerIds.clearBit(pointerId);
1799 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001800 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001801 continue;
1802 }
1803 }
1804 i += 1;
1805 }
1806 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001807 }
1808
1809 // Save changes unless the action was scroll in which case the temporary touch
1810 // state was only valid for this one action.
1811 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1812 if (mTempTouchState.displayId >= 0) {
1813 if (oldStateIndex >= 0) {
1814 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1815 } else {
1816 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1817 }
1818 } else if (oldStateIndex >= 0) {
1819 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1820 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001821 }
1822
1823 // Update hover state.
1824 mLastHoverWindowHandle = newHoverWindowHandle;
1825 }
1826 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001827 if (DEBUG_FOCUS) {
1828 ALOGD("Not updating touch focus because injection was denied.");
1829 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001830 }
1831
1832Unresponsive:
1833 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1834 mTempTouchState.reset();
1835
1836 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001837 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001838 if (DEBUG_FOCUS) {
1839 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1840 "timeSpentWaitingForApplication=%0.1fms",
1841 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1842 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001843 return injectionResult;
1844}
1845
1846void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001847 int32_t targetFlags, BitSet32 pointerIds,
1848 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00001849 std::vector<InputTarget>::iterator it =
1850 std::find_if(inputTargets.begin(), inputTargets.end(),
1851 [&windowHandle](const InputTarget& inputTarget) {
1852 return inputTarget.inputChannel->getConnectionToken() ==
1853 windowHandle->getToken();
1854 });
chaviw5d22a232019-12-11 16:47:32 -08001855
Chavi Weingartenb38d8c62020-01-08 21:20:39 +00001856 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00001857
1858 if (it == inputTargets.end()) {
1859 InputTarget inputTarget;
1860 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1861 if (inputChannel == nullptr) {
1862 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1863 return;
1864 }
1865 inputTarget.inputChannel = inputChannel;
1866 inputTarget.flags = targetFlags;
1867 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
1868 inputTargets.push_back(inputTarget);
1869 it = inputTargets.end() - 1;
1870 }
1871
1872 ALOG_ASSERT(it->flags == targetFlags);
1873 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
1874
1875 it->addPointers(pointerIds, -windowInfo->frameLeft, -windowInfo->frameTop,
1876 windowInfo->windowXScale, windowInfo->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001877}
1878
Michael Wright3dd60e22019-03-27 22:06:44 +00001879void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001880 int32_t displayId, float xOffset,
1881 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001882 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1883 mGlobalMonitorsByDisplay.find(displayId);
1884
1885 if (it != mGlobalMonitorsByDisplay.end()) {
1886 const std::vector<Monitor>& monitors = it->second;
1887 for (const Monitor& monitor : monitors) {
1888 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001889 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001890 }
1891}
1892
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001893void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
1894 float yOffset,
1895 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001896 InputTarget target;
1897 target.inputChannel = monitor.inputChannel;
1898 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00001899 target.setDefaultPointerInfo(xOffset, yOffset, 1 /* windowXScale */, 1 /* windowYScale */);
Michael Wright3dd60e22019-03-27 22:06:44 +00001900 inputTargets.push_back(target);
1901}
1902
Michael Wrightd02c5b62014-02-10 15:10:22 -08001903bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001904 const InjectionState* injectionState) {
1905 if (injectionState &&
1906 (windowHandle == nullptr ||
1907 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
1908 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001909 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001910 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001911 "owned by uid %d",
1912 injectionState->injectorPid, injectionState->injectorUid,
1913 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001914 } else {
1915 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001916 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001917 }
1918 return false;
1919 }
1920 return true;
1921}
1922
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001923bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
1924 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001925 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001926 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1927 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001928 if (otherHandle == windowHandle) {
1929 break;
1930 }
1931
1932 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001933 if (otherInfo->displayId == displayId && otherInfo->visible &&
1934 !otherInfo->isTrustedOverlay() && otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001935 return true;
1936 }
1937 }
1938 return false;
1939}
1940
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001941bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1942 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001943 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001944 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001945 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001946 if (otherHandle == windowHandle) {
1947 break;
1948 }
1949
1950 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001951 if (otherInfo->displayId == displayId && otherInfo->visible &&
1952 !otherInfo->isTrustedOverlay() && otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001953 return true;
1954 }
1955 }
1956 return false;
1957}
1958
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001959std::string InputDispatcher::checkWindowReadyForMoreInputLocked(
1960 nsecs_t currentTime, const sp<InputWindowHandle>& windowHandle,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001961 const EventEntry& eventEntry, const char* targetType) {
Jeff Brownffb49772014-10-10 19:01:34 -07001962 // If the window is paused then keep waiting.
1963 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001964 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001965 }
1966
1967 // If the window's connection is not registered then keep waiting.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001968 sp<Connection> connection = getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001969 if (connection == nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001970 return StringPrintf("Waiting because the %s window's input channel is not "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001971 "registered with the input dispatcher. The window may be in the "
1972 "process of being removed.",
1973 targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001974 }
1975
1976 // If the connection is dead then keep waiting.
Jeff Brownffb49772014-10-10 19:01:34 -07001977 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001978 return StringPrintf("Waiting because the %s window's input connection is %s."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001979 "The window may be in the process of being removed.",
1980 targetType, connection->getStatusLabel());
Jeff Brownffb49772014-10-10 19:01:34 -07001981 }
1982
1983 // If the connection is backed up then keep waiting.
1984 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001985 return StringPrintf("Waiting because the %s window's input channel is full. "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001986 "Outbound queue length: %zu. Wait queue length: %zu.",
1987 targetType, connection->outboundQueue.size(),
1988 connection->waitQueue.size());
Jeff Brownffb49772014-10-10 19:01:34 -07001989 }
1990
1991 // Ensure that the dispatch queues aren't too far backed up for this event.
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001992 if (eventEntry.type == EventEntry::Type::KEY) {
Jeff Brownffb49772014-10-10 19:01:34 -07001993 // If the event is a key event, then we must wait for all previous events to
1994 // complete before delivering it because previous events may have the
1995 // side-effect of transferring focus to a different window and we want to
1996 // ensure that the following keys are sent to the new window.
1997 //
1998 // Suppose the user touches a button in a window then immediately presses "A".
1999 // If the button causes a pop-up window to appear then we want to ensure that
2000 // the "A" key is delivered to the new pop-up window. This is because users
2001 // often anticipate pending UI changes when typing on a keyboard.
2002 // To obtain this behavior, we must serialize key events with respect to all
2003 // prior input events.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002004 if (!connection->outboundQueue.empty() || !connection->waitQueue.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002005 return StringPrintf("Waiting to send key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002006 "finished processing all of the input events that were previously "
2007 "delivered to it. Outbound queue length: %zu. Wait queue length: "
2008 "%zu.",
2009 targetType, connection->outboundQueue.size(),
2010 connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002011 }
Jeff Brownffb49772014-10-10 19:01:34 -07002012 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002013 // Touch events can always be sent to a window immediately because the user intended
2014 // to touch whatever was visible at the time. Even if focus changes or a new
2015 // window appears moments later, the touch event was meant to be delivered to
2016 // whatever window happened to be on screen at the time.
2017 //
2018 // Generic motion events, such as trackball or joystick events are a little trickier.
2019 // Like key events, generic motion events are delivered to the focused window.
2020 // Unlike key events, generic motion events don't tend to transfer focus to other
2021 // windows and it is not important for them to be serialized. So we prefer to deliver
2022 // generic motion events as soon as possible to improve efficiency and reduce lag
2023 // through batching.
2024 //
2025 // The one case where we pause input event delivery is when the wait queue is piling
2026 // up with lots of events because the application is not responding.
2027 // This condition ensures that ANRs are detected reliably.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002028 if (!connection->waitQueue.empty() &&
2029 currentTime >=
2030 connection->waitQueue.front()->deliveryTime + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002031 return StringPrintf("Waiting to send non-key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002032 "finished processing certain input events that were delivered to "
2033 "it over "
2034 "%0.1fms ago. Wait queue length: %zu. Wait queue head age: "
2035 "%0.1fms.",
2036 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
2037 connection->waitQueue.size(),
2038 (currentTime - connection->waitQueue.front()->deliveryTime) *
2039 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002040 }
2041 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002042 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002043}
2044
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002045std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002046 const sp<InputApplicationHandle>& applicationHandle,
2047 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002048 if (applicationHandle != nullptr) {
2049 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002050 std::string label(applicationHandle->getName());
2051 label += " - ";
2052 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002053 return label;
2054 } else {
2055 return applicationHandle->getName();
2056 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002057 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002058 return windowHandle->getName();
2059 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002060 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002061 }
2062}
2063
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002064void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08002065 int32_t displayId = getTargetDisplayId(eventEntry);
2066 sp<InputWindowHandle> focusedWindowHandle =
2067 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
2068 if (focusedWindowHandle != nullptr) {
2069 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002070 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
2071#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002072 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002073#endif
2074 return;
2075 }
2076 }
2077
2078 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002079 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002080 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002081 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2082 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002083 return;
2084 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002085
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002086 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002087 eventType = USER_ACTIVITY_EVENT_TOUCH;
2088 }
2089 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002090 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002091 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002092 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2093 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002094 return;
2095 }
2096 eventType = USER_ACTIVITY_EVENT_BUTTON;
2097 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002098 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002099 case EventEntry::Type::CONFIGURATION_CHANGED:
2100 case EventEntry::Type::DEVICE_RESET: {
2101 LOG_ALWAYS_FATAL("%s events are not user activity",
2102 EventEntry::typeToString(eventEntry.type));
2103 break;
2104 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002105 }
2106
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002107 std::unique_ptr<CommandEntry> commandEntry =
2108 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002109 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002110 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002111 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002112}
2113
2114void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002115 const sp<Connection>& connection,
2116 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002117 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002118 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002119 std::string message =
2120 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2121 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002122 ATRACE_NAME(message.c_str());
2123 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002124#if DEBUG_DISPATCH_CYCLE
2125 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002126 "globalScaleFactor=%f, pointerIds=0x%x %s",
2127 connection->getInputChannelName().c_str(), inputTarget.flags,
2128 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2129 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002130#endif
2131
2132 // Skip this event if the connection status is not normal.
2133 // We don't want to enqueue additional outbound events if the connection is broken.
2134 if (connection->status != Connection::STATUS_NORMAL) {
2135#if DEBUG_DISPATCH_CYCLE
2136 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002137 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002138#endif
2139 return;
2140 }
2141
2142 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002143 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2144 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2145 "Entry type %s should not have FLAG_SPLIT",
2146 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002147
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002148 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002149 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002150 MotionEntry* splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002151 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002152 if (!splitMotionEntry) {
2153 return; // split event was dropped
2154 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002155 if (DEBUG_FOCUS) {
2156 ALOGD("channel '%s' ~ Split motion event.",
2157 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002158 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002159 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002160 enqueueDispatchEntriesLocked(currentTime, connection, splitMotionEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002161 splitMotionEntry->release();
2162 return;
2163 }
2164 }
2165
2166 // Not splitting. Enqueue dispatch entries for the event as is.
2167 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2168}
2169
2170void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002171 const sp<Connection>& connection,
2172 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002173 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002174 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002175 std::string message =
2176 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32
2177 ")",
2178 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002179 ATRACE_NAME(message.c_str());
2180 }
2181
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002182 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002183
2184 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002185 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002186 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002187 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002188 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002189 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002190 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002191 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002192 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002193 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002194 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002195 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002196 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002197
2198 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002199 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002200 startDispatchCycleLocked(currentTime, connection);
2201 }
2202}
2203
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002204void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
2205 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002206 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002207 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002208 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002209 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2210 connection->getInputChannelName().c_str(),
2211 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002212 ATRACE_NAME(message.c_str());
2213 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002214 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002215 if (!(inputTargetFlags & dispatchMode)) {
2216 return;
2217 }
2218 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2219
2220 // This is a new event.
2221 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002222 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002223 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002224
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002225 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2226 // different EventEntry than what was passed in.
2227 EventEntry* newEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002228 // Apply target flags and update the connection's input state.
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002229 switch (newEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002230 case EventEntry::Type::KEY: {
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002231 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*newEntry);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002232 dispatchEntry->resolvedAction = keyEntry.action;
2233 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002234
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002235 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2236 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002237#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002238 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2239 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002240#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002241 return; // skip the inconsistent event
2242 }
2243 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002244 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002245
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002246 case EventEntry::Type::MOTION: {
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002247 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*newEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002248 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2249 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2250 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2251 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2252 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2253 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2254 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2255 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2256 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2257 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2258 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002259 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002260 }
2261 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002262 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2263 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002264#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002265 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2266 "event",
2267 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002268#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002269 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2270 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002271
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002272 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002273 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2274 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2275 }
2276 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2277 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2278 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002279
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002280 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2281 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002282#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002283 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2284 "event",
2285 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002286#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002287 return; // skip the inconsistent event
2288 }
2289
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002290 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002291 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002292
2293 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002294 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002295 case EventEntry::Type::CONFIGURATION_CHANGED:
2296 case EventEntry::Type::DEVICE_RESET: {
2297 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002298 EventEntry::typeToString(newEntry->type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002299 break;
2300 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002301 }
2302
2303 // Remember that we are waiting for this dispatch to complete.
2304 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002305 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002306 }
2307
2308 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002309 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002310 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002311}
2312
chaviwfd6d3512019-03-25 13:23:49 -07002313void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002314 const sp<IBinder>& newToken) {
chaviw8c9cf542019-03-25 13:02:48 -07002315 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002316 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2317 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002318 return;
2319 }
2320
2321 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2322 if (inputWindowHandle == nullptr) {
2323 return;
2324 }
2325
chaviw8c9cf542019-03-25 13:02:48 -07002326 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002327 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002328
2329 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2330
2331 if (!hasFocusChanged) {
2332 return;
2333 }
2334
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002335 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2336 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002337 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002338 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002339}
2340
2341void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002342 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002343 if (ATRACE_ENABLED()) {
2344 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002345 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002346 ATRACE_NAME(message.c_str());
2347 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002348#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002349 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002350#endif
2351
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002352 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2353 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002354 dispatchEntry->deliveryTime = currentTime;
2355
2356 // Publish the event.
2357 status_t status;
2358 EventEntry* eventEntry = dispatchEntry->eventEntry;
2359 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002360 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002361 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002362
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002363 // Publish the key event.
2364 status = connection->inputPublisher
2365 .publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId,
2366 keyEntry->source, keyEntry->displayId,
2367 dispatchEntry->resolvedAction,
2368 dispatchEntry->resolvedFlags, keyEntry->keyCode,
2369 keyEntry->scanCode, keyEntry->metaState,
2370 keyEntry->repeatCount, keyEntry->downTime,
2371 keyEntry->eventTime);
2372 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002373 }
2374
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002375 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002376 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002377
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002378 PointerCoords scaledCoords[MAX_POINTERS];
2379 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2380
2381 // Set the X and Y offset depending on the input source.
2382 float xOffset, yOffset;
2383 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
2384 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2385 float globalScaleFactor = dispatchEntry->globalScaleFactor;
2386 float wxs = dispatchEntry->windowXScale;
2387 float wys = dispatchEntry->windowYScale;
2388 xOffset = dispatchEntry->xOffset * wxs;
2389 yOffset = dispatchEntry->yOffset * wys;
2390 if (wxs != 1.0f || wys != 1.0f || globalScaleFactor != 1.0f) {
2391 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2392 scaledCoords[i] = motionEntry->pointerCoords[i];
2393 scaledCoords[i].scale(globalScaleFactor, wxs, wys);
2394 }
2395 usingCoords = scaledCoords;
2396 }
2397 } else {
2398 xOffset = 0.0f;
2399 yOffset = 0.0f;
2400
2401 // We don't want the dispatch target to know.
2402 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
2403 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2404 scaledCoords[i].clear();
2405 }
2406 usingCoords = scaledCoords;
2407 }
2408 }
2409
2410 // Publish the motion event.
2411 status = connection->inputPublisher
2412 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2413 motionEntry->source, motionEntry->displayId,
2414 dispatchEntry->resolvedAction,
2415 motionEntry->actionButton,
2416 dispatchEntry->resolvedFlags,
2417 motionEntry->edgeFlags, motionEntry->metaState,
2418 motionEntry->buttonState,
2419 motionEntry->classification, xOffset, yOffset,
2420 motionEntry->xPrecision,
2421 motionEntry->yPrecision,
2422 motionEntry->xCursorPosition,
2423 motionEntry->yCursorPosition,
2424 motionEntry->downTime, motionEntry->eventTime,
2425 motionEntry->pointerCount,
2426 motionEntry->pointerProperties, usingCoords);
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05002427 reportTouchEventForStatistics(*motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002428 break;
2429 }
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002430 case EventEntry::Type::CONFIGURATION_CHANGED:
2431 case EventEntry::Type::DEVICE_RESET: {
2432 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
2433 EventEntry::typeToString(eventEntry->type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002434 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002435 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002436 }
2437
2438 // Check the result.
2439 if (status) {
2440 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002441 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002442 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002443 "This is unexpected because the wait queue is empty, so the pipe "
2444 "should be empty and we shouldn't have any problems writing an "
2445 "event to it, status=%d",
2446 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002447 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2448 } else {
2449 // Pipe is full and we are waiting for the app to finish process some events
2450 // before sending more events to it.
2451#if DEBUG_DISPATCH_CYCLE
2452 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002453 "waiting for the application to catch up",
2454 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002455#endif
2456 connection->inputPublisherBlocked = true;
2457 }
2458 } else {
2459 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002460 "status=%d",
2461 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002462 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2463 }
2464 return;
2465 }
2466
2467 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002468 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2469 connection->outboundQueue.end(),
2470 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002471 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002472 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002473 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002474 }
2475}
2476
2477void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002478 const sp<Connection>& connection, uint32_t seq,
2479 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002480#if DEBUG_DISPATCH_CYCLE
2481 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002482 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002483#endif
2484
2485 connection->inputPublisherBlocked = false;
2486
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002487 if (connection->status == Connection::STATUS_BROKEN ||
2488 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002489 return;
2490 }
2491
2492 // Notify other system components and prepare to start the next dispatch cycle.
2493 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2494}
2495
2496void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002497 const sp<Connection>& connection,
2498 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002499#if DEBUG_DISPATCH_CYCLE
2500 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002501 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002502#endif
2503
2504 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002505 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002506 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002507 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002508 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002509
2510 // The connection appears to be unrecoverably broken.
2511 // Ignore already broken or zombie connections.
2512 if (connection->status == Connection::STATUS_NORMAL) {
2513 connection->status = Connection::STATUS_BROKEN;
2514
2515 if (notify) {
2516 // Notify other system components.
2517 onDispatchCycleBrokenLocked(currentTime, connection);
2518 }
2519 }
2520}
2521
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002522void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2523 while (!queue.empty()) {
2524 DispatchEntry* dispatchEntry = queue.front();
2525 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002526 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002527 }
2528}
2529
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002530void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002531 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002532 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002533 }
2534 delete dispatchEntry;
2535}
2536
2537int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2538 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2539
2540 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002541 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002542
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002543 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002544 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002545 "fd=%d, events=0x%x",
2546 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002547 return 0; // remove the callback
2548 }
2549
2550 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002551 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002552 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2553 if (!(events & ALOOPER_EVENT_INPUT)) {
2554 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002555 "events=0x%x",
2556 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002557 return 1;
2558 }
2559
2560 nsecs_t currentTime = now();
2561 bool gotOne = false;
2562 status_t status;
2563 for (;;) {
2564 uint32_t seq;
2565 bool handled;
2566 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2567 if (status) {
2568 break;
2569 }
2570 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2571 gotOne = true;
2572 }
2573 if (gotOne) {
2574 d->runCommandsLockedInterruptible();
2575 if (status == WOULD_BLOCK) {
2576 return 1;
2577 }
2578 }
2579
2580 notify = status != DEAD_OBJECT || !connection->monitor;
2581 if (notify) {
2582 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002583 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002584 }
2585 } else {
2586 // Monitor channels are never explicitly unregistered.
2587 // We do it automatically when the remote endpoint is closed so don't warn
2588 // about them.
2589 notify = !connection->monitor;
2590 if (notify) {
2591 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002592 "events=0x%x",
2593 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002594 }
2595 }
2596
2597 // Unregister the channel.
2598 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2599 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002600 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08002601}
2602
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002603void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002604 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002605 for (const auto& pair : mConnectionsByFd) {
2606 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002607 }
2608}
2609
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002610void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002611 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002612 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2613 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2614}
2615
2616void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2617 const CancelationOptions& options,
2618 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2619 for (const auto& it : monitorsByDisplay) {
2620 const std::vector<Monitor>& monitors = it.second;
2621 for (const Monitor& monitor : monitors) {
2622 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002623 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002624 }
2625}
2626
Michael Wrightd02c5b62014-02-10 15:10:22 -08002627void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2628 const sp<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002629 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002630 if (connection == nullptr) {
2631 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002632 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002633
2634 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002635}
2636
2637void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2638 const sp<Connection>& connection, const CancelationOptions& options) {
2639 if (connection->status == Connection::STATUS_BROKEN) {
2640 return;
2641 }
2642
2643 nsecs_t currentTime = now();
2644
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07002645 std::vector<EventEntry*> cancelationEvents =
2646 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002647
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002648 if (!cancelationEvents.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002649#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002650 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002651 "with reality: %s, mode=%d.",
2652 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
2653 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002654#endif
2655 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002656 EventEntry* cancelationEventEntry = cancelationEvents[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002657 switch (cancelationEventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002658 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002659 logOutboundKeyDetails("cancel - ",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002660 static_cast<const KeyEntry&>(*cancelationEventEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002661 break;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002662 }
2663 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002664 logOutboundMotionDetails("cancel - ",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002665 static_cast<const MotionEntry&>(
2666 *cancelationEventEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002667 break;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002668 }
2669 case EventEntry::Type::CONFIGURATION_CHANGED:
2670 case EventEntry::Type::DEVICE_RESET: {
2671 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2672 EventEntry::typeToString(cancelationEventEntry->type));
2673 break;
2674 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002675 }
2676
2677 InputTarget target;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002678 sp<InputWindowHandle> windowHandle =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002679 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07002680 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002681 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002682 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2683 windowInfo->windowXScale, windowInfo->windowYScale);
Robert Carre07e1032018-11-26 12:55:53 -08002684 target.globalScaleFactor = windowInfo->globalScaleFactor;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002685 }
2686 target.inputChannel = connection->inputChannel;
2687 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2688
chaviw8c9cf542019-03-25 13:02:48 -07002689 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002690 target, InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002691
2692 cancelationEventEntry->release();
2693 }
2694
2695 startDispatchCycleLocked(currentTime, connection);
2696 }
2697}
2698
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002699MotionEntry* InputDispatcher::splitMotionEvent(const MotionEntry& originalMotionEntry,
Garfield Tane84e6f92019-08-29 17:28:41 -07002700 BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002701 ALOG_ASSERT(pointerIds.value != 0);
2702
2703 uint32_t splitPointerIndexMap[MAX_POINTERS];
2704 PointerProperties splitPointerProperties[MAX_POINTERS];
2705 PointerCoords splitPointerCoords[MAX_POINTERS];
2706
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002707 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002708 uint32_t splitPointerCount = 0;
2709
2710 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002711 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002712 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002713 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002714 uint32_t pointerId = uint32_t(pointerProperties.id);
2715 if (pointerIds.hasBit(pointerId)) {
2716 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2717 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2718 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002719 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002720 splitPointerCount += 1;
2721 }
2722 }
2723
2724 if (splitPointerCount != pointerIds.count()) {
2725 // This is bad. We are missing some of the pointers that we expected to deliver.
2726 // Most likely this indicates that we received an ACTION_MOVE events that has
2727 // different pointer ids than we expected based on the previous ACTION_DOWN
2728 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2729 // in this way.
2730 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002731 "we expected there to be %d pointers. This probably means we received "
2732 "a broken sequence of pointer ids from the input device.",
2733 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002734 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002735 }
2736
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002737 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002738 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002739 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
2740 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002741 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2742 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002743 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002744 uint32_t pointerId = uint32_t(pointerProperties.id);
2745 if (pointerIds.hasBit(pointerId)) {
2746 if (pointerIds.count() == 1) {
2747 // The first/last pointer went down/up.
2748 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002749 ? AMOTION_EVENT_ACTION_DOWN
2750 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002751 } else {
2752 // A secondary pointer went down/up.
2753 uint32_t splitPointerIndex = 0;
2754 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2755 splitPointerIndex += 1;
2756 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002757 action = maskedAction |
2758 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002759 }
2760 } else {
2761 // An unrelated pointer changed.
2762 action = AMOTION_EVENT_ACTION_MOVE;
2763 }
2764 }
2765
Garfield Tan00f511d2019-06-12 16:55:40 -07002766 MotionEntry* splitMotionEntry =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002767 new MotionEntry(originalMotionEntry.sequenceNum, originalMotionEntry.eventTime,
2768 originalMotionEntry.deviceId, originalMotionEntry.source,
2769 originalMotionEntry.displayId, originalMotionEntry.policyFlags, action,
2770 originalMotionEntry.actionButton, originalMotionEntry.flags,
2771 originalMotionEntry.metaState, originalMotionEntry.buttonState,
2772 originalMotionEntry.classification, originalMotionEntry.edgeFlags,
2773 originalMotionEntry.xPrecision, originalMotionEntry.yPrecision,
2774 originalMotionEntry.xCursorPosition,
2775 originalMotionEntry.yCursorPosition, originalMotionEntry.downTime,
Garfield Tan00f511d2019-06-12 16:55:40 -07002776 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002777
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002778 if (originalMotionEntry.injectionState) {
2779 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002780 splitMotionEntry->injectionState->refCount += 1;
2781 }
2782
2783 return splitMotionEntry;
2784}
2785
2786void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2787#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002788 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002789#endif
2790
2791 bool needWake;
2792 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002793 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002794
Prabir Pradhan42611e02018-11-27 14:04:02 -08002795 ConfigurationChangedEntry* newEntry =
2796 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002797 needWake = enqueueInboundEventLocked(newEntry);
2798 } // release lock
2799
2800 if (needWake) {
2801 mLooper->wake();
2802 }
2803}
2804
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002805/**
2806 * If one of the meta shortcuts is detected, process them here:
2807 * Meta + Backspace -> generate BACK
2808 * Meta + Enter -> generate HOME
2809 * This will potentially overwrite keyCode and metaState.
2810 */
2811void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002812 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002813 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2814 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2815 if (keyCode == AKEYCODE_DEL) {
2816 newKeyCode = AKEYCODE_BACK;
2817 } else if (keyCode == AKEYCODE_ENTER) {
2818 newKeyCode = AKEYCODE_HOME;
2819 }
2820 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002821 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002822 struct KeyReplacement replacement = {keyCode, deviceId};
2823 mReplacedKeys.add(replacement, newKeyCode);
2824 keyCode = newKeyCode;
2825 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2826 }
2827 } else if (action == AKEY_EVENT_ACTION_UP) {
2828 // In order to maintain a consistent stream of up and down events, check to see if the key
2829 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2830 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002831 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002832 struct KeyReplacement replacement = {keyCode, deviceId};
2833 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2834 if (index >= 0) {
2835 keyCode = mReplacedKeys.valueAt(index);
2836 mReplacedKeys.removeItemsAt(index);
2837 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2838 }
2839 }
2840}
2841
Michael Wrightd02c5b62014-02-10 15:10:22 -08002842void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2843#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002844 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
2845 "policyFlags=0x%x, action=0x%x, "
2846 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
2847 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2848 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
2849 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002850#endif
2851 if (!validateKeyEvent(args->action)) {
2852 return;
2853 }
2854
2855 uint32_t policyFlags = args->policyFlags;
2856 int32_t flags = args->flags;
2857 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002858 // InputDispatcher tracks and generates key repeats on behalf of
2859 // whatever notifies it, so repeatCount should always be set to 0
2860 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002861 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2862 policyFlags |= POLICY_FLAG_VIRTUAL;
2863 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2864 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002865 if (policyFlags & POLICY_FLAG_FUNCTION) {
2866 metaState |= AMETA_FUNCTION_ON;
2867 }
2868
2869 policyFlags |= POLICY_FLAG_TRUSTED;
2870
Michael Wright78f24442014-08-06 15:55:28 -07002871 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002872 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002873
Michael Wrightd02c5b62014-02-10 15:10:22 -08002874 KeyEvent event;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002875 event.initialize(args->deviceId, args->source, args->displayId, args->action, flags, keyCode,
2876 args->scanCode, metaState, repeatCount, args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002877
Michael Wright2b3c3302018-03-02 17:19:13 +00002878 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002879 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002880 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2881 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002882 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00002883 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002884
Michael Wrightd02c5b62014-02-10 15:10:22 -08002885 bool needWake;
2886 { // acquire lock
2887 mLock.lock();
2888
2889 if (shouldSendKeyToInputFilterLocked(args)) {
2890 mLock.unlock();
2891
2892 policyFlags |= POLICY_FLAG_FILTERED;
2893 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2894 return; // event was consumed by the filter
2895 }
2896
2897 mLock.lock();
2898 }
2899
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002900 KeyEntry* newEntry =
2901 new KeyEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2902 args->displayId, policyFlags, args->action, flags, keyCode,
2903 args->scanCode, metaState, repeatCount, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002904
2905 needWake = enqueueInboundEventLocked(newEntry);
2906 mLock.unlock();
2907 } // release lock
2908
2909 if (needWake) {
2910 mLooper->wake();
2911 }
2912}
2913
2914bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2915 return mInputFilterEnabled;
2916}
2917
2918void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2919#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002920 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07002921 ", policyFlags=0x%x, "
2922 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
2923 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07002924 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07002925 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2926 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
Jaewan Kim372fbe42019-10-02 10:58:46 +09002927 args->edgeFlags, args->xPrecision, args->yPrecision, args->xCursorPosition,
Garfield Tan00f511d2019-06-12 16:55:40 -07002928 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002929 for (uint32_t i = 0; i < args->pointerCount; i++) {
2930 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002931 "x=%f, y=%f, pressure=%f, size=%f, "
2932 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2933 "orientation=%f",
2934 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
2935 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2936 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2937 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2938 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2939 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2940 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2941 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2942 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2943 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002944 }
2945#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002946 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
2947 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002948 return;
2949 }
2950
2951 uint32_t policyFlags = args->policyFlags;
2952 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00002953
2954 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002955 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002956 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2957 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002958 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00002959 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002960
2961 bool needWake;
2962 { // acquire lock
2963 mLock.lock();
2964
2965 if (shouldSendMotionToInputFilterLocked(args)) {
2966 mLock.unlock();
2967
2968 MotionEvent event;
Garfield Tan00f511d2019-06-12 16:55:40 -07002969 event.initialize(args->deviceId, args->source, args->displayId, args->action,
2970 args->actionButton, args->flags, args->edgeFlags, args->metaState,
2971 args->buttonState, args->classification, 0, 0, args->xPrecision,
2972 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2973 args->downTime, args->eventTime, args->pointerCount,
2974 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002975
2976 policyFlags |= POLICY_FLAG_FILTERED;
2977 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2978 return; // event was consumed by the filter
2979 }
2980
2981 mLock.lock();
2982 }
2983
2984 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002985 MotionEntry* newEntry =
2986 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2987 args->displayId, policyFlags, args->action, args->actionButton,
2988 args->flags, args->metaState, args->buttonState,
2989 args->classification, args->edgeFlags, args->xPrecision,
2990 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2991 args->downTime, args->pointerCount, args->pointerProperties,
2992 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002993
2994 needWake = enqueueInboundEventLocked(newEntry);
2995 mLock.unlock();
2996 } // release lock
2997
2998 if (needWake) {
2999 mLooper->wake();
3000 }
3001}
3002
3003bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003004 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003005}
3006
3007void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3008#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003009 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003010 "switchMask=0x%08x",
3011 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003012#endif
3013
3014 uint32_t policyFlags = args->policyFlags;
3015 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003016 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003017}
3018
3019void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3020#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003021 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3022 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003023#endif
3024
3025 bool needWake;
3026 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003027 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003028
Prabir Pradhan42611e02018-11-27 14:04:02 -08003029 DeviceResetEntry* newEntry =
3030 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003031 needWake = enqueueInboundEventLocked(newEntry);
3032 } // release lock
3033
3034 if (needWake) {
3035 mLooper->wake();
3036 }
3037}
3038
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003039int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid,
3040 int32_t injectorUid, int32_t syncMode,
3041 int32_t timeoutMillis, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003042#if DEBUG_INBOUND_EVENT_DETAILS
3043 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003044 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
3045 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003046#endif
3047
3048 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
3049
3050 policyFlags |= POLICY_FLAG_INJECTED;
3051 if (hasInjectionPermission(injectorPid, injectorUid)) {
3052 policyFlags |= POLICY_FLAG_TRUSTED;
3053 }
3054
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003055 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003056 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003057 case AINPUT_EVENT_TYPE_KEY: {
3058 KeyEvent keyEvent;
3059 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
3060 int32_t action = keyEvent.getAction();
3061 if (!validateKeyEvent(action)) {
3062 return INPUT_EVENT_INJECTION_FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003063 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003064
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003065 int32_t flags = keyEvent.getFlags();
3066 int32_t keyCode = keyEvent.getKeyCode();
3067 int32_t metaState = keyEvent.getMetaState();
3068 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
3069 /*byref*/ keyCode, /*byref*/ metaState);
3070 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(),
3071 keyEvent.getDisplayId(), action, flags, keyCode,
3072 keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
3073 keyEvent.getDownTime(), keyEvent.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003074
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003075 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3076 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003077 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003078
3079 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3080 android::base::Timer t;
3081 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3082 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3083 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3084 std::to_string(t.duration().count()).c_str());
3085 }
3086 }
3087
3088 mLock.lock();
3089 KeyEntry* injectedEntry =
3090 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
3091 keyEvent.getDeviceId(), keyEvent.getSource(),
3092 keyEvent.getDisplayId(), policyFlags, action, flags,
3093 keyEvent.getKeyCode(), keyEvent.getScanCode(),
3094 keyEvent.getMetaState(), keyEvent.getRepeatCount(),
3095 keyEvent.getDownTime());
3096 injectedEntries.push(injectedEntry);
3097 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003098 }
3099
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003100 case AINPUT_EVENT_TYPE_MOTION: {
3101 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3102 int32_t action = motionEvent->getAction();
3103 size_t pointerCount = motionEvent->getPointerCount();
3104 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3105 int32_t actionButton = motionEvent->getActionButton();
3106 int32_t displayId = motionEvent->getDisplayId();
3107 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
3108 return INPUT_EVENT_INJECTION_FAILED;
3109 }
3110
3111 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3112 nsecs_t eventTime = motionEvent->getEventTime();
3113 android::base::Timer t;
3114 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3115 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3116 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3117 std::to_string(t.duration().count()).c_str());
3118 }
3119 }
3120
3121 mLock.lock();
3122 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3123 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
3124 MotionEntry* injectedEntry =
Garfield Tan00f511d2019-06-12 16:55:40 -07003125 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3126 motionEvent->getDeviceId(), motionEvent->getSource(),
3127 motionEvent->getDisplayId(), policyFlags, action, actionButton,
3128 motionEvent->getFlags(), motionEvent->getMetaState(),
3129 motionEvent->getButtonState(), motionEvent->getClassification(),
3130 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3131 motionEvent->getYPrecision(),
3132 motionEvent->getRawXCursorPosition(),
3133 motionEvent->getRawYCursorPosition(),
3134 motionEvent->getDownTime(), uint32_t(pointerCount),
3135 pointerProperties, samplePointerCoords,
3136 motionEvent->getXOffset(), motionEvent->getYOffset());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003137 injectedEntries.push(injectedEntry);
3138 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3139 sampleEventTimes += 1;
3140 samplePointerCoords += pointerCount;
3141 MotionEntry* nextInjectedEntry =
3142 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3143 motionEvent->getDeviceId(), motionEvent->getSource(),
3144 motionEvent->getDisplayId(), policyFlags, action,
3145 actionButton, motionEvent->getFlags(),
3146 motionEvent->getMetaState(), motionEvent->getButtonState(),
3147 motionEvent->getClassification(),
3148 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3149 motionEvent->getYPrecision(),
3150 motionEvent->getRawXCursorPosition(),
3151 motionEvent->getRawYCursorPosition(),
3152 motionEvent->getDownTime(), uint32_t(pointerCount),
3153 pointerProperties, samplePointerCoords,
3154 motionEvent->getXOffset(), motionEvent->getYOffset());
3155 injectedEntries.push(nextInjectedEntry);
3156 }
3157 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003158 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003159
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003160 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003161 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003162 return INPUT_EVENT_INJECTION_FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003163 }
3164
3165 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3166 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3167 injectionState->injectionIsAsync = true;
3168 }
3169
3170 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003171 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003172
3173 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003174 while (!injectedEntries.empty()) {
3175 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3176 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003177 }
3178
3179 mLock.unlock();
3180
3181 if (needWake) {
3182 mLooper->wake();
3183 }
3184
3185 int32_t injectionResult;
3186 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003187 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003188
3189 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3190 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3191 } else {
3192 for (;;) {
3193 injectionResult = injectionState->injectionResult;
3194 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3195 break;
3196 }
3197
3198 nsecs_t remainingTimeout = endTime - now();
3199 if (remainingTimeout <= 0) {
3200#if DEBUG_INJECTION
3201 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003202 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003203#endif
3204 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3205 break;
3206 }
3207
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003208 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003209 }
3210
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003211 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED &&
3212 syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003213 while (injectionState->pendingForegroundDispatches != 0) {
3214#if DEBUG_INJECTION
3215 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003216 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003217#endif
3218 nsecs_t remainingTimeout = endTime - now();
3219 if (remainingTimeout <= 0) {
3220#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003221 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3222 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003223#endif
3224 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3225 break;
3226 }
3227
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003228 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003229 }
3230 }
3231 }
3232
3233 injectionState->release();
3234 } // release lock
3235
3236#if DEBUG_INJECTION
3237 ALOGD("injectInputEvent - Finished with result %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003238 "injectorPid=%d, injectorUid=%d",
3239 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003240#endif
3241
3242 return injectionResult;
3243}
3244
3245bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003246 return injectorUid == 0 ||
3247 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003248}
3249
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003250void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003251 InjectionState* injectionState = entry->injectionState;
3252 if (injectionState) {
3253#if DEBUG_INJECTION
3254 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003255 "injectorPid=%d, injectorUid=%d",
3256 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003257#endif
3258
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003259 if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003260 // Log the outcome since the injector did not wait for the injection result.
3261 switch (injectionResult) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003262 case INPUT_EVENT_INJECTION_SUCCEEDED:
3263 ALOGV("Asynchronous input event injection succeeded.");
3264 break;
3265 case INPUT_EVENT_INJECTION_FAILED:
3266 ALOGW("Asynchronous input event injection failed.");
3267 break;
3268 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3269 ALOGW("Asynchronous input event injection permission denied.");
3270 break;
3271 case INPUT_EVENT_INJECTION_TIMED_OUT:
3272 ALOGW("Asynchronous input event injection timed out.");
3273 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003274 }
3275 }
3276
3277 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003278 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003279 }
3280}
3281
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003282void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003283 InjectionState* injectionState = entry->injectionState;
3284 if (injectionState) {
3285 injectionState->pendingForegroundDispatches += 1;
3286 }
3287}
3288
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003289void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003290 InjectionState* injectionState = entry->injectionState;
3291 if (injectionState) {
3292 injectionState->pendingForegroundDispatches -= 1;
3293
3294 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003295 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003296 }
3297 }
3298}
3299
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003300std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3301 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003302 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003303}
3304
Michael Wrightd02c5b62014-02-10 15:10:22 -08003305sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003306 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003307 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003308 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3309 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003310 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003311 return windowHandle;
3312 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003313 }
3314 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003315 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003316}
3317
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003318bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003319 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003320 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3321 for (const sp<InputWindowHandle>& handle : windowHandles) {
3322 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003323 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003324 ALOGE("Found window %s in display %" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003325 ", but it should belong to display %" PRId32,
3326 windowHandle->getName().c_str(), it.first,
3327 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003328 }
3329 return true;
3330 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003331 }
3332 }
3333 return false;
3334}
3335
Robert Carr5c8a0262018-10-03 16:30:44 -07003336sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3337 size_t count = mInputChannelsByToken.count(token);
3338 if (count == 0) {
3339 return nullptr;
3340 }
3341 return mInputChannelsByToken.at(token);
3342}
3343
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003344void InputDispatcher::updateWindowHandlesForDisplayLocked(
3345 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3346 if (inputWindowHandles.empty()) {
3347 // Remove all handles on a display if there are no windows left.
3348 mWindowHandlesByDisplay.erase(displayId);
3349 return;
3350 }
3351
3352 // Since we compare the pointer of input window handles across window updates, we need
3353 // to make sure the handle object for the same window stays unchanged across updates.
3354 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003355 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003356 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003357 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003358 }
3359
3360 std::vector<sp<InputWindowHandle>> newHandles;
3361 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3362 if (!handle->updateInfo()) {
3363 // handle no longer valid
3364 continue;
3365 }
3366
3367 const InputWindowInfo* info = handle->getInfo();
3368 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3369 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3370 const bool noInputChannel =
3371 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3372 const bool canReceiveInput =
3373 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3374 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3375 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003376 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003377 handle->getName().c_str());
3378 }
3379 continue;
3380 }
3381
3382 if (info->displayId != displayId) {
3383 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3384 handle->getName().c_str(), displayId, info->displayId);
3385 continue;
3386 }
3387
chaviwaf87b3e2019-10-01 16:59:28 -07003388 if (oldHandlesById.find(handle->getId()) != oldHandlesById.end()) {
3389 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003390 oldHandle->updateFrom(handle);
3391 newHandles.push_back(oldHandle);
3392 } else {
3393 newHandles.push_back(handle);
3394 }
3395 }
3396
3397 // Insert or replace
3398 mWindowHandlesByDisplay[displayId] = newHandles;
3399}
3400
Arthur Hungb92218b2018-08-14 12:00:21 +08003401/**
3402 * Called from InputManagerService, update window handle list by displayId that can receive input.
3403 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3404 * If set an empty list, remove all handles from the specific display.
3405 * For focused handle, check if need to change and send a cancel event to previous one.
3406 * For removed handle, check if need to send a cancel event if already in touch.
3407 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003408void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003409 int32_t displayId,
3410 const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003411 if (DEBUG_FOCUS) {
3412 std::string windowList;
3413 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
3414 windowList += iwh->getName() + " ";
3415 }
3416 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
3417 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003418 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003419 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003420
Arthur Hungb92218b2018-08-14 12:00:21 +08003421 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003422 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3423 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003424
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003425 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3426
Tiger Huang721e26f2018-07-24 22:26:19 +08003427 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003428 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003429 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3430 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3431 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3432 windowHandle->getInfo()->visible) {
3433 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003434 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003435 if (windowHandle == mLastHoverWindowHandle) {
3436 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003437 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003438 }
3439
3440 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003441 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003442 }
3443
Tiger Huang721e26f2018-07-24 22:26:19 +08003444 sp<InputWindowHandle> oldFocusedWindowHandle =
3445 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3446
chaviwaf87b3e2019-10-01 16:59:28 -07003447 if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003448 if (oldFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003449 if (DEBUG_FOCUS) {
3450 ALOGD("Focus left window: %s in display %" PRId32,
3451 oldFocusedWindowHandle->getName().c_str(), displayId);
3452 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003453 sp<InputChannel> focusedInputChannel =
3454 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003455 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003456 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003457 "focus left window");
3458 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003459 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003460 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003461 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003462 if (newFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003463 if (DEBUG_FOCUS) {
3464 ALOGD("Focus entered window: %s in display %" PRId32,
3465 newFocusedWindowHandle->getName().c_str(), displayId);
3466 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003467 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003468 }
Robert Carrf759f162018-11-13 12:57:11 -08003469
3470 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003471 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003472 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003473 }
3474
Arthur Hungb92218b2018-08-14 12:00:21 +08003475 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3476 if (stateIndex >= 0) {
3477 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003478 for (size_t i = 0; i < state.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003479 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003480 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003481 if (DEBUG_FOCUS) {
3482 ALOGD("Touched window was removed: %s in display %" PRId32,
3483 touchedWindow.windowHandle->getName().c_str(), displayId);
3484 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003485 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003486 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003487 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003488 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003489 "touched window was removed");
3490 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
3491 options);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003492 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003493 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003494 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003495 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003496 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003497 }
3498 }
3499
3500 // Release information for windows that are no longer present.
3501 // This ensures that unused input channels are released promptly.
3502 // Otherwise, they might stick around until the window handle is destroyed
3503 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003504 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003505 if (!hasWindowHandleLocked(oldWindowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003506 if (DEBUG_FOCUS) {
3507 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
3508 }
Arthur Hung3b413f22018-10-26 18:05:34 +08003509 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003510 }
3511 }
3512 } // release lock
3513
3514 // Wake up poll loop since it may need to make new input dispatching choices.
3515 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003516
3517 if (setInputWindowsListener) {
3518 setInputWindowsListener->onSetInputWindowsFinished();
3519 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003520}
3521
3522void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003523 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003524 if (DEBUG_FOCUS) {
3525 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
3526 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
3527 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003528 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003529 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003530
Tiger Huang721e26f2018-07-24 22:26:19 +08003531 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3532 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003533 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003534 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3535 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003536 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003537 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003538 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003539 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003540 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003541 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003542 oldFocusedApplicationHandle.clear();
3543 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003544 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003545 } // release lock
3546
3547 // Wake up poll loop since it may need to make new input dispatching choices.
3548 mLooper->wake();
3549}
3550
Tiger Huang721e26f2018-07-24 22:26:19 +08003551/**
3552 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3553 * the display not specified.
3554 *
3555 * We track any unreleased events for each window. If a window loses the ability to receive the
3556 * released event, we will send a cancel event to it. So when the focused display is changed, we
3557 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3558 * display. The display-specified events won't be affected.
3559 */
3560void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003561 if (DEBUG_FOCUS) {
3562 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3563 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003564 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003565 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003566
3567 if (mFocusedDisplayId != displayId) {
3568 sp<InputWindowHandle> oldFocusedWindowHandle =
3569 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3570 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003571 sp<InputChannel> inputChannel =
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003572 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003573 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003574 CancelationOptions
3575 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3576 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003577 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003578 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3579 }
3580 }
3581 mFocusedDisplayId = displayId;
3582
3583 // Sanity check
3584 sp<InputWindowHandle> newFocusedWindowHandle =
3585 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003586 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003587
Tiger Huang721e26f2018-07-24 22:26:19 +08003588 if (newFocusedWindowHandle == nullptr) {
3589 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3590 if (!mFocusedWindowHandlesByDisplay.empty()) {
3591 ALOGE("But another display has a focused window:");
3592 for (auto& it : mFocusedWindowHandlesByDisplay) {
3593 const int32_t displayId = it.first;
3594 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003595 ALOGE("Display #%" PRId32 " has focused window: '%s'\n", displayId,
3596 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003597 }
3598 }
3599 }
3600 }
3601
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003602 if (DEBUG_FOCUS) {
3603 logDispatchStateLocked();
3604 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003605 } // release lock
3606
3607 // Wake up poll loop since it may need to make new input dispatching choices.
3608 mLooper->wake();
3609}
3610
Michael Wrightd02c5b62014-02-10 15:10:22 -08003611void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003612 if (DEBUG_FOCUS) {
3613 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3614 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003615
3616 bool changed;
3617 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003618 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003619
3620 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3621 if (mDispatchFrozen && !frozen) {
3622 resetANRTimeoutsLocked();
3623 }
3624
3625 if (mDispatchEnabled && !enabled) {
3626 resetAndDropEverythingLocked("dispatcher is being disabled");
3627 }
3628
3629 mDispatchEnabled = enabled;
3630 mDispatchFrozen = frozen;
3631 changed = true;
3632 } else {
3633 changed = false;
3634 }
3635
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003636 if (DEBUG_FOCUS) {
3637 logDispatchStateLocked();
3638 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003639 } // release lock
3640
3641 if (changed) {
3642 // Wake up poll loop since it may need to make new input dispatching choices.
3643 mLooper->wake();
3644 }
3645}
3646
3647void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003648 if (DEBUG_FOCUS) {
3649 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3650 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003651
3652 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003653 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003654
3655 if (mInputFilterEnabled == enabled) {
3656 return;
3657 }
3658
3659 mInputFilterEnabled = enabled;
3660 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3661 } // release lock
3662
3663 // Wake up poll loop since there might be work to do to drop everything.
3664 mLooper->wake();
3665}
3666
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08003667void InputDispatcher::setInTouchMode(bool inTouchMode) {
3668 std::scoped_lock lock(mLock);
3669 mInTouchMode = inTouchMode;
3670}
3671
chaviwfbe5d9c2018-12-26 12:23:37 -08003672bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3673 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003674 if (DEBUG_FOCUS) {
3675 ALOGD("Trivial transfer to same window.");
3676 }
chaviwfbe5d9c2018-12-26 12:23:37 -08003677 return true;
3678 }
3679
Michael Wrightd02c5b62014-02-10 15:10:22 -08003680 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003681 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003682
chaviwfbe5d9c2018-12-26 12:23:37 -08003683 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3684 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003685 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003686 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003687 return false;
3688 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003689 if (DEBUG_FOCUS) {
3690 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3691 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3692 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003693 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003694 if (DEBUG_FOCUS) {
3695 ALOGD("Cannot transfer focus because windows are on different displays.");
3696 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003697 return false;
3698 }
3699
3700 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003701 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3702 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3703 for (size_t i = 0; i < state.windows.size(); i++) {
3704 const TouchedWindow& touchedWindow = state.windows[i];
3705 if (touchedWindow.windowHandle == fromWindowHandle) {
3706 int32_t oldTargetFlags = touchedWindow.targetFlags;
3707 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003708
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003709 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003710
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003711 int32_t newTargetFlags = oldTargetFlags &
3712 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
3713 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003714 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003715
Jeff Brownf086ddb2014-02-11 14:28:48 -08003716 found = true;
3717 goto Found;
3718 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003719 }
3720 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003721 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003722
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003723 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003724 if (DEBUG_FOCUS) {
3725 ALOGD("Focus transfer failed because from window did not have focus.");
3726 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003727 return false;
3728 }
3729
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07003730 sp<Connection> fromConnection = getConnectionLocked(fromToken);
3731 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003732 if (fromConnection != nullptr && toConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003733 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003734 CancelationOptions
3735 options(CancelationOptions::CANCEL_POINTER_EVENTS,
3736 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003737 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
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 // Wake up poll loop since it may need to make new input dispatching choices.
3746 mLooper->wake();
3747 return true;
3748}
3749
3750void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003751 if (DEBUG_FOCUS) {
3752 ALOGD("Resetting and dropping all events (%s).", reason);
3753 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003754
3755 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3756 synthesizeCancelationEventsForAllConnectionsLocked(options);
3757
3758 resetKeyRepeatLocked();
3759 releasePendingEventLocked();
3760 drainInboundQueueLocked();
3761 resetANRTimeoutsLocked();
3762
Jeff Brownf086ddb2014-02-11 14:28:48 -08003763 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003764 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003765 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003766}
3767
3768void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003769 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003770 dumpDispatchStateLocked(dump);
3771
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003772 std::istringstream stream(dump);
3773 std::string line;
3774
3775 while (std::getline(stream, line, '\n')) {
3776 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003777 }
3778}
3779
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003780void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003781 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3782 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3783 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003784 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003785
Tiger Huang721e26f2018-07-24 22:26:19 +08003786 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3787 dump += StringPrintf(INDENT "FocusedApplications:\n");
3788 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3789 const int32_t displayId = it.first;
3790 const sp<InputApplicationHandle>& applicationHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003791 dump += StringPrintf(INDENT2 "displayId=%" PRId32
3792 ", name='%s', dispatchingTimeout=%0.3fms\n",
3793 displayId, applicationHandle->getName().c_str(),
3794 applicationHandle->getDispatchingTimeout(
3795 DEFAULT_INPUT_DISPATCHING_TIMEOUT) /
3796 1000000.0);
Tiger Huang721e26f2018-07-24 22:26:19 +08003797 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003798 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003799 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003800 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003801
3802 if (!mFocusedWindowHandlesByDisplay.empty()) {
3803 dump += StringPrintf(INDENT "FocusedWindows:\n");
3804 for (auto& it : mFocusedWindowHandlesByDisplay) {
3805 const int32_t displayId = it.first;
3806 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003807 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
3808 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003809 }
3810 } else {
3811 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3812 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003813
Jeff Brownf086ddb2014-02-11 14:28:48 -08003814 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003815 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003816 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3817 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003818 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003819 state.displayId, toString(state.down), toString(state.split),
3820 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003821 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003822 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003823 for (size_t i = 0; i < state.windows.size(); i++) {
3824 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003825 dump += StringPrintf(INDENT4
3826 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3827 i, touchedWindow.windowHandle->getName().c_str(),
3828 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003829 }
3830 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003831 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003832 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003833 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003834 dump += INDENT3 "Portal windows:\n";
3835 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003836 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003837 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
3838 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003839 }
3840 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003841 }
3842 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003843 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003844 }
3845
Arthur Hungb92218b2018-08-14 12:00:21 +08003846 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003847 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003848 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003849 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003850 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003851 dump += INDENT2 "Windows:\n";
3852 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003853 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003854 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003855
Arthur Hungb92218b2018-08-14 12:00:21 +08003856 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003857 "portalToDisplayId=%d, paused=%s, hasFocus=%s, "
chaviwcb923212019-12-30 14:05:11 -08003858 "hasWallpaper=%s, visible=%s, canReceiveKeys=%s, "
3859 "flags=0x%08x, type=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003860 "frame=[%d,%d][%d,%d], globalScale=%f, "
chaviwcb923212019-12-30 14:05:11 -08003861 "windowScale=(%f,%f), touchableRegion=",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003862 i, windowInfo->name.c_str(), windowInfo->displayId,
3863 windowInfo->portalToDisplayId,
3864 toString(windowInfo->paused),
3865 toString(windowInfo->hasFocus),
3866 toString(windowInfo->hasWallpaper),
3867 toString(windowInfo->visible),
3868 toString(windowInfo->canReceiveKeys),
3869 windowInfo->layoutParamsFlags,
chaviwcb923212019-12-30 14:05:11 -08003870 windowInfo->layoutParamsType, windowInfo->frameLeft,
3871 windowInfo->frameTop, windowInfo->frameRight,
3872 windowInfo->frameBottom, windowInfo->globalScaleFactor,
3873 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003874 dumpRegion(dump, windowInfo->touchableRegion);
3875 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3876 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003877 windowInfo->ownerPid, windowInfo->ownerUid,
3878 windowInfo->dispatchingTimeout / 1000000.0);
Arthur Hungb92218b2018-08-14 12:00:21 +08003879 }
3880 } else {
3881 dump += INDENT2 "Windows: <none>\n";
3882 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003883 }
3884 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003885 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003886 }
3887
Michael Wright3dd60e22019-03-27 22:06:44 +00003888 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003889 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003890 const std::vector<Monitor>& monitors = it.second;
3891 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3892 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003893 }
3894 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003895 const std::vector<Monitor>& monitors = it.second;
3896 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
3897 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003898 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003899 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00003900 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003901 }
3902
3903 nsecs_t currentTime = now();
3904
3905 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003906 if (!mRecentQueue.empty()) {
3907 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
3908 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003909 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003910 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003911 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003912 }
3913 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003914 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003915 }
3916
3917 // Dump event currently being dispatched.
3918 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003919 dump += INDENT "PendingEvent:\n";
3920 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003921 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003922 dump += StringPrintf(", age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003923 (currentTime - mPendingEvent->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003924 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003925 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003926 }
3927
3928 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003929 if (!mInboundQueue.empty()) {
3930 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
3931 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003932 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003933 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003934 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003935 }
3936 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003937 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003938 }
3939
Michael Wright78f24442014-08-06 15:55:28 -07003940 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003941 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07003942 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
3943 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
3944 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003945 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n", i,
3946 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07003947 }
3948 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003949 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07003950 }
3951
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003952 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003953 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003954 for (const auto& pair : mConnectionsByFd) {
3955 const sp<Connection>& connection = pair.second;
3956 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
3957 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
3958 pair.first, connection->getInputChannelName().c_str(),
3959 connection->getWindowName().c_str(), connection->getStatusLabel(),
3960 toString(connection->monitor),
3961 toString(connection->inputPublisherBlocked));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003963 if (!connection->outboundQueue.empty()) {
3964 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
3965 connection->outboundQueue.size());
3966 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003967 dump.append(INDENT4);
3968 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003969 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003970 entry->targetFlags, entry->resolvedAction,
3971 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003972 }
3973 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003974 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003975 }
3976
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003977 if (!connection->waitQueue.empty()) {
3978 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
3979 connection->waitQueue.size());
3980 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003981 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003982 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003983 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003984 "age=%0.1fms, wait=%0.1fms\n",
3985 entry->targetFlags, entry->resolvedAction,
3986 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
3987 (currentTime - entry->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003988 }
3989 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003990 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003991 }
3992 }
3993 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003994 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003995 }
3996
3997 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003998 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003999 (mAppSwitchDueTime - now()) / 1000000.0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004000 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004001 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004002 }
4003
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004004 dump += INDENT "Configuration:\n";
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004005 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004006 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004007 mConfig.keyRepeatTimeout * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004008}
4009
Michael Wright3dd60e22019-03-27 22:06:44 +00004010void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4011 const size_t numMonitors = monitors.size();
4012 for (size_t i = 0; i < numMonitors; i++) {
4013 const Monitor& monitor = monitors[i];
4014 const sp<InputChannel>& channel = monitor.inputChannel;
4015 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4016 dump += "\n";
4017 }
4018}
4019
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004020status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004021#if DEBUG_REGISTRATION
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004022 ALOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004023#endif
4024
4025 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004026 std::scoped_lock _l(mLock);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004027 sp<Connection> existingConnection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004028 if (existingConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004029 ALOGW("Attempted to register already registered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004030 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004031 return BAD_VALUE;
4032 }
4033
Michael Wright3dd60e22019-03-27 22:06:44 +00004034 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004035
4036 int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004037 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004038 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004039
Michael Wrightd02c5b62014-02-10 15:10:22 -08004040 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4041 } // release lock
4042
4043 // Wake the looper because some connections have changed.
4044 mLooper->wake();
4045 return OK;
4046}
4047
Michael Wright3dd60e22019-03-27 22:06:44 +00004048status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004049 int32_t displayId, bool isGestureMonitor) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004050 { // acquire lock
4051 std::scoped_lock _l(mLock);
4052
4053 if (displayId < 0) {
4054 ALOGW("Attempted to register input monitor without a specified display.");
4055 return BAD_VALUE;
4056 }
4057
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004058 if (inputChannel->getConnectionToken() == nullptr) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004059 ALOGW("Attempted to register input monitor without an identifying token.");
4060 return BAD_VALUE;
4061 }
4062
4063 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
4064
4065 const int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004066 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004067 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004068
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004069 auto& monitorsByDisplay =
4070 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Michael Wright3dd60e22019-03-27 22:06:44 +00004071 monitorsByDisplay[displayId].emplace_back(inputChannel);
4072
4073 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004074 }
4075 // Wake the looper because some connections have changed.
4076 mLooper->wake();
4077 return OK;
4078}
4079
Michael Wrightd02c5b62014-02-10 15:10:22 -08004080status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
4081#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004082 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004083#endif
4084
4085 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004086 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004087
4088 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
4089 if (status) {
4090 return status;
4091 }
4092 } // release lock
4093
4094 // Wake the poll loop because removing the connection may have changed the current
4095 // synchronization state.
4096 mLooper->wake();
4097 return OK;
4098}
4099
4100status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004101 bool notify) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004102 sp<Connection> connection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004103 if (connection == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004104 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004105 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004106 return BAD_VALUE;
4107 }
4108
John Recke0710582019-09-26 13:46:12 -07004109 [[maybe_unused]] const bool removed = removeByValue(mConnectionsByFd, connection);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004110 ALOG_ASSERT(removed);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004111 mInputChannelsByToken.erase(inputChannel->getConnectionToken());
Robert Carr5c8a0262018-10-03 16:30:44 -07004112
Michael Wrightd02c5b62014-02-10 15:10:22 -08004113 if (connection->monitor) {
4114 removeMonitorChannelLocked(inputChannel);
4115 }
4116
4117 mLooper->removeFd(inputChannel->getFd());
4118
4119 nsecs_t currentTime = now();
4120 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4121
4122 connection->status = Connection::STATUS_ZOMBIE;
4123 return OK;
4124}
4125
4126void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004127 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4128 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4129}
4130
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004131void InputDispatcher::removeMonitorChannelLocked(
4132 const sp<InputChannel>& inputChannel,
Michael Wright3dd60e22019-03-27 22:06:44 +00004133 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004134 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004135 std::vector<Monitor>& monitors = it->second;
4136 const size_t numMonitors = monitors.size();
4137 for (size_t i = 0; i < numMonitors; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004138 if (monitors[i].inputChannel == inputChannel) {
4139 monitors.erase(monitors.begin() + i);
4140 break;
4141 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004142 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004143 if (monitors.empty()) {
4144 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004145 } else {
4146 ++it;
4147 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004148 }
4149}
4150
Michael Wright3dd60e22019-03-27 22:06:44 +00004151status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4152 { // acquire lock
4153 std::scoped_lock _l(mLock);
4154 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4155
4156 if (!foundDisplayId) {
4157 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4158 return BAD_VALUE;
4159 }
4160 int32_t displayId = foundDisplayId.value();
4161
4162 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4163 if (stateIndex < 0) {
4164 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4165 return BAD_VALUE;
4166 }
4167
4168 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4169 std::optional<int32_t> foundDeviceId;
4170 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004171 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004172 foundDeviceId = state.deviceId;
4173 }
4174 }
4175 if (!foundDeviceId || !state.down) {
4176 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004177 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004178 return BAD_VALUE;
4179 }
4180 int32_t deviceId = foundDeviceId.value();
4181
4182 // Send cancel events to all the input channels we're stealing from.
4183 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004184 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004185 options.deviceId = deviceId;
4186 options.displayId = displayId;
4187 for (const TouchedWindow& window : state.windows) {
4188 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004189 if (channel != nullptr) {
4190 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4191 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004192 }
4193 // Then clear the current touch state so we stop dispatching to them as well.
4194 state.filterNonMonitors();
4195 }
4196 return OK;
4197}
4198
Michael Wright3dd60e22019-03-27 22:06:44 +00004199std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4200 const sp<IBinder>& token) {
4201 for (const auto& it : mGestureMonitorsByDisplay) {
4202 const std::vector<Monitor>& monitors = it.second;
4203 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004204 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004205 return it.first;
4206 }
4207 }
4208 }
4209 return std::nullopt;
4210}
4211
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004212sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) {
4213 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004214 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004215 }
4216
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004217 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004218 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004219 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004220 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004221 }
4222 }
Robert Carr4e670e52018-08-15 13:26:12 -07004223
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004224 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004225}
4226
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004227void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4228 const sp<Connection>& connection, uint32_t seq,
4229 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004230 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4231 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004232 commandEntry->connection = connection;
4233 commandEntry->eventTime = currentTime;
4234 commandEntry->seq = seq;
4235 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004236 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004237}
4238
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004239void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4240 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004241 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004242 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004243
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004244 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4245 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004246 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004247 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004248}
4249
chaviw0c06c6e2019-01-09 13:27:07 -08004250void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004251 const sp<InputWindowHandle>& newFocus) {
chaviw0c06c6e2019-01-09 13:27:07 -08004252 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4253 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004254 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4255 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004256 commandEntry->oldToken = oldToken;
4257 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004258 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004259}
4260
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004261void InputDispatcher::onANRLocked(nsecs_t currentTime,
4262 const sp<InputApplicationHandle>& applicationHandle,
4263 const sp<InputWindowHandle>& windowHandle, nsecs_t eventTime,
4264 nsecs_t waitStartTime, const char* reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004265 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4266 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4267 ALOGI("Application is not responding: %s. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004268 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
4269 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), dispatchLatency,
4270 waitDuration, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004271
4272 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004273 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004274 struct tm tm;
4275 localtime_r(&t, &tm);
4276 char timestr[64];
4277 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4278 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004279 mLastANRState += INDENT "ANR:\n";
4280 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004281 mLastANRState +=
4282 StringPrintf(INDENT2 "Window: %s\n",
4283 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004284 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4285 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4286 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004287 dumpDispatchStateLocked(mLastANRState);
4288
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004289 std::unique_ptr<CommandEntry> commandEntry =
4290 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004291 commandEntry->inputApplicationHandle = applicationHandle;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004292 commandEntry->inputChannel =
4293 windowHandle != nullptr ? getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004294 commandEntry->reason = reason;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004295 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004296}
4297
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004298void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004299 mLock.unlock();
4300
4301 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4302
4303 mLock.lock();
4304}
4305
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004306void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004307 sp<Connection> connection = commandEntry->connection;
4308
4309 if (connection->status != Connection::STATUS_ZOMBIE) {
4310 mLock.unlock();
4311
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004312 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004313
4314 mLock.lock();
4315 }
4316}
4317
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004318void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004319 sp<IBinder> oldToken = commandEntry->oldToken;
4320 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004321 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004322 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004323 mLock.lock();
4324}
4325
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004326void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004327 sp<IBinder> token =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004328 commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004329 mLock.unlock();
4330
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004331 nsecs_t newTimeout =
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004332 mPolicy->notifyANR(commandEntry->inputApplicationHandle, token, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004333
4334 mLock.lock();
4335
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004336 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004337}
4338
4339void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4340 CommandEntry* commandEntry) {
4341 KeyEntry* entry = commandEntry->keyEntry;
4342
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004343 KeyEvent event = createKeyEvent(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004344
4345 mLock.unlock();
4346
Michael Wright2b3c3302018-03-02 17:19:13 +00004347 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004348 sp<IBinder> token = commandEntry->inputChannel != nullptr
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004349 ? commandEntry->inputChannel->getConnectionToken()
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004350 : nullptr;
4351 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004352 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4353 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004354 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004355 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004356
4357 mLock.lock();
4358
4359 if (delay < 0) {
4360 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4361 } else if (!delay) {
4362 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4363 } else {
4364 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4365 entry->interceptKeyWakeupTime = now() + delay;
4366 }
4367 entry->release();
4368}
4369
chaviwfd6d3512019-03-25 13:23:49 -07004370void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4371 mLock.unlock();
4372 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4373 mLock.lock();
4374}
4375
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004376void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004377 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004378 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004379 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004380 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004381
4382 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07004383 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004384 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004385 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004386 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004387 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004388
4389 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4390 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4391 std::string msg =
4392 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4393 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4394 dispatchEntry->eventEntry->appendDescription(msg);
4395 ALOGI("%s", msg.c_str());
4396 }
4397
4398 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004399 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004400 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4401 restartEvent =
4402 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004403 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004404 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4405 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4406 handled);
4407 } else {
4408 restartEvent = false;
4409 }
4410
4411 // Dequeue the event and start the next cycle.
4412 // Note that because the lock might have been released, it is possible that the
4413 // contents of the wait queue to have been drained, so we need to double-check
4414 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004415 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4416 if (dispatchEntryIt != connection->waitQueue.end()) {
4417 dispatchEntry = *dispatchEntryIt;
4418 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004419 traceWaitQueueLength(connection);
4420 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004421 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004422 traceOutboundQueueLength(connection);
4423 } else {
4424 releaseDispatchEntry(dispatchEntry);
4425 }
4426 }
4427
4428 // Start the next dispatch cycle for this connection.
4429 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004430}
4431
4432bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004433 DispatchEntry* dispatchEntry,
4434 KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004435 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004436 if (!handled) {
4437 // Report the key as unhandled, since the fallback was not handled.
4438 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4439 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004440 return false;
4441 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004442
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004443 // Get the fallback key state.
4444 // Clear it out after dispatching the UP.
4445 int32_t originalKeyCode = keyEntry->keyCode;
4446 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4447 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4448 connection->inputState.removeFallbackKey(originalKeyCode);
4449 }
4450
4451 if (handled || !dispatchEntry->hasForegroundTarget()) {
4452 // If the application handles the original key for which we previously
4453 // generated a fallback or if the window is not a foreground window,
4454 // then cancel the associated fallback key, if any.
4455 if (fallbackKeyCode != -1) {
4456 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004457#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004458 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004459 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4460 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4461 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004462#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004463 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004464 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004465
4466 mLock.unlock();
4467
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004468 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004469 keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004470
4471 mLock.lock();
4472
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004473 // Cancel the fallback key.
4474 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004475 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004476 "application handled the original non-fallback key "
4477 "or is no longer a foreground target, "
4478 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004479 options.keyCode = fallbackKeyCode;
4480 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004481 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004482 connection->inputState.removeFallbackKey(originalKeyCode);
4483 }
4484 } else {
4485 // If the application did not handle a non-fallback key, first check
4486 // that we are in a good state to perform unhandled key event processing
4487 // Then ask the policy what to do with it.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004488 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN && keyEntry->repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004489 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004490#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004491 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004492 "since this is not an initial down. "
4493 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4494 originalKeyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004495#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004496 return false;
4497 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004498
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004499 // Dispatch the unhandled key to the policy.
4500#if DEBUG_OUTBOUND_EVENT_DETAILS
4501 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004502 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4503 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004504#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004505 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004506
4507 mLock.unlock();
4508
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004509 bool fallback =
4510 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
4511 &event, keyEntry->policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004512
4513 mLock.lock();
4514
4515 if (connection->status != Connection::STATUS_NORMAL) {
4516 connection->inputState.removeFallbackKey(originalKeyCode);
4517 return false;
4518 }
4519
4520 // Latch the fallback keycode for this key on an initial down.
4521 // The fallback keycode cannot change at any other point in the lifecycle.
4522 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004523 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004524 fallbackKeyCode = event.getKeyCode();
4525 } else {
4526 fallbackKeyCode = AKEYCODE_UNKNOWN;
4527 }
4528 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4529 }
4530
4531 ALOG_ASSERT(fallbackKeyCode != -1);
4532
4533 // Cancel the fallback key if the policy decides not to send it anymore.
4534 // We will continue to dispatch the key to the policy but we will no
4535 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004536 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
4537 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004538#if DEBUG_OUTBOUND_EVENT_DETAILS
4539 if (fallback) {
4540 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004541 "as a fallback for %d, but on the DOWN it had requested "
4542 "to send %d instead. Fallback canceled.",
4543 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004544 } else {
4545 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004546 "but on the DOWN it had requested to send %d. "
4547 "Fallback canceled.",
4548 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004549 }
4550#endif
4551
4552 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4553 "canceling fallback, policy no longer desires it");
4554 options.keyCode = fallbackKeyCode;
4555 synthesizeCancelationEventsForConnectionLocked(connection, options);
4556
4557 fallback = false;
4558 fallbackKeyCode = AKEYCODE_UNKNOWN;
4559 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004560 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004561 }
4562 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004563
4564#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004565 {
4566 std::string msg;
4567 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4568 connection->inputState.getFallbackKeys();
4569 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004570 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004571 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004572 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004573 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004574 }
4575#endif
4576
4577 if (fallback) {
4578 // Restart the dispatch cycle using the fallback key.
4579 keyEntry->eventTime = event.getEventTime();
4580 keyEntry->deviceId = event.getDeviceId();
4581 keyEntry->source = event.getSource();
4582 keyEntry->displayId = event.getDisplayId();
4583 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4584 keyEntry->keyCode = fallbackKeyCode;
4585 keyEntry->scanCode = event.getScanCode();
4586 keyEntry->metaState = event.getMetaState();
4587 keyEntry->repeatCount = event.getRepeatCount();
4588 keyEntry->downTime = event.getDownTime();
4589 keyEntry->syntheticRepeat = false;
4590
4591#if DEBUG_OUTBOUND_EVENT_DETAILS
4592 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004593 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4594 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004595#endif
4596 return true; // restart the event
4597 } else {
4598#if DEBUG_OUTBOUND_EVENT_DETAILS
4599 ALOGD("Unhandled key event: No fallback key.");
4600#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004601
4602 // Report the key as unhandled, since there is no fallback key.
4603 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004604 }
4605 }
4606 return false;
4607}
4608
4609bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004610 DispatchEntry* dispatchEntry,
4611 MotionEntry* motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004612 return false;
4613}
4614
4615void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4616 mLock.unlock();
4617
4618 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4619
4620 mLock.lock();
4621}
4622
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004623KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
4624 KeyEvent event;
4625 event.initialize(entry.deviceId, entry.source, entry.displayId, entry.action, entry.flags,
4626 entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount,
4627 entry.downTime, entry.eventTime);
4628 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004629}
4630
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004631void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004632 int32_t injectionResult,
4633 nsecs_t timeSpentWaitingForApplication) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004634 // TODO Write some statistics about how long we spend waiting.
4635}
4636
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05004637/**
4638 * Report the touch event latency to the statsd server.
4639 * Input events are reported for statistics if:
4640 * - This is a touchscreen event
4641 * - InputFilter is not enabled
4642 * - Event is not injected or synthesized
4643 *
4644 * Statistics should be reported before calling addValue, to prevent a fresh new sample
4645 * from getting aggregated with the "old" data.
4646 */
4647void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
4648 REQUIRES(mLock) {
4649 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
4650 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
4651 if (!reportForStatistics) {
4652 return;
4653 }
4654
4655 if (mTouchStatistics.shouldReport()) {
4656 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
4657 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
4658 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
4659 mTouchStatistics.reset();
4660 }
4661 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
4662 mTouchStatistics.addValue(latencyMicros);
4663}
4664
Michael Wrightd02c5b62014-02-10 15:10:22 -08004665void InputDispatcher::traceInboundQueueLengthLocked() {
4666 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004667 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004668 }
4669}
4670
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004671void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004672 if (ATRACE_ENABLED()) {
4673 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004674 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004675 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004676 }
4677}
4678
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004679void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004680 if (ATRACE_ENABLED()) {
4681 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004682 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004683 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004684 }
4685}
4686
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004687void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004688 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004689
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004690 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004691 dumpDispatchStateLocked(dump);
4692
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004693 if (!mLastANRState.empty()) {
4694 dump += "\nInput Dispatcher State at time of last ANR:\n";
4695 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004696 }
4697}
4698
4699void InputDispatcher::monitor() {
4700 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004701 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004702 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004703 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004704}
4705
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08004706/**
4707 * Wake up the dispatcher and wait until it processes all events and commands.
4708 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
4709 * this method can be safely called from any thread, as long as you've ensured that
4710 * the work you are interested in completing has already been queued.
4711 */
4712bool InputDispatcher::waitForIdle() {
4713 /**
4714 * Timeout should represent the longest possible time that a device might spend processing
4715 * events and commands.
4716 */
4717 constexpr std::chrono::duration TIMEOUT = 100ms;
4718 std::unique_lock lock(mLock);
4719 mLooper->wake();
4720 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
4721 return result == std::cv_status::no_timeout;
4722}
4723
Garfield Tane84e6f92019-08-29 17:28:41 -07004724} // namespace android::inputdispatcher