blob: 3635f3b00a9322795bf8a45b1c12ab1c543899da [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
31// Log debug messages about registrations.
32#define DEBUG_REGISTRATION 0
33
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
Siarhei Vishniakou86587282019-09-09 18:20:15 +010038static constexpr bool DEBUG_FOCUS = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -080039
40// Log debug messages about the app switch latency optimization.
41#define DEBUG_APP_SWITCH 0
42
43// Log debug messages about hover events.
44#define DEBUG_HOVER 0
45
46#include "InputDispatcher.h"
47
Garfield Tane84e6f92019-08-29 17:28:41 -070048#include "Connection.h"
49
Michael Wrightd02c5b62014-02-10 15:10:22 -080050#include <errno.h>
Siarhei Vishniakou443ad902019-03-06 17:25:41 -080051#include <inttypes.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080052#include <limits.h>
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -050053#include <statslog.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070054#include <stddef.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080055#include <time.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070056#include <unistd.h>
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -070057#include <queue>
58#include <sstream>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070059
Michael Wright2b3c3302018-03-02 17:19:13 +000060#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080061#include <android-base/stringprintf.h>
Robert Carr4e670e52018-08-15 13:26:12 -070062#include <binder/Binder.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070063#include <log/log.h>
64#include <powermanager/PowerManager.h>
65#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080066
67#define INDENT " "
68#define INDENT2 " "
69#define INDENT3 " "
70#define INDENT4 " "
71
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080072using android::base::StringPrintf;
73
Garfield Tane84e6f92019-08-29 17:28:41 -070074namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080075
76// Default input dispatching timeout if there is no focused application or paused window
77// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000078constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080079
80// Amount of time to allow for all pending events to be processed when an app switch
81// key is on the way. This is used to preempt input dispatch and drop input events
82// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000083constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080084
85// Amount of time to allow for an event to be dispatched (measured since its eventTime)
86// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000087constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080088
89// Amount of time to allow touch events to be streamed out to a connection before requiring
90// that the first event be finished. This value extends the ANR timeout by the specified
91// amount. For example, if streaming is allowed to get ahead by one second relative to the
92// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000093constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080094
95// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +000096constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
97
98// Log a warning when an interception call takes longer than this to process.
99constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800100
101// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000102constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
103
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104static inline nsecs_t now() {
105 return systemTime(SYSTEM_TIME_MONOTONIC);
106}
107
108static inline const char* toString(bool value) {
109 return value ? "true" : "false";
110}
111
112static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700113 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
114 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115}
116
117static bool isValidKeyAction(int32_t action) {
118 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700119 case AKEY_EVENT_ACTION_DOWN:
120 case AKEY_EVENT_ACTION_UP:
121 return true;
122 default:
123 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800124 }
125}
126
127static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700128 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800129 ALOGE("Key event has invalid action code 0x%x", action);
130 return false;
131 }
132 return true;
133}
134
Michael Wright7b159c92015-05-14 14:48:03 +0100135static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800136 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700137 case AMOTION_EVENT_ACTION_DOWN:
138 case AMOTION_EVENT_ACTION_UP:
139 case AMOTION_EVENT_ACTION_CANCEL:
140 case AMOTION_EVENT_ACTION_MOVE:
141 case AMOTION_EVENT_ACTION_OUTSIDE:
142 case AMOTION_EVENT_ACTION_HOVER_ENTER:
143 case AMOTION_EVENT_ACTION_HOVER_MOVE:
144 case AMOTION_EVENT_ACTION_HOVER_EXIT:
145 case AMOTION_EVENT_ACTION_SCROLL:
146 return true;
147 case AMOTION_EVENT_ACTION_POINTER_DOWN:
148 case AMOTION_EVENT_ACTION_POINTER_UP: {
149 int32_t index = getMotionEventActionPointerIndex(action);
150 return index >= 0 && index < pointerCount;
151 }
152 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
153 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
154 return actionButton != 0;
155 default:
156 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800157 }
158}
159
Michael Wright7b159c92015-05-14 14:48:03 +0100160static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700161 const PointerProperties* pointerProperties) {
162 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800163 ALOGE("Motion event has invalid action code 0x%x", action);
164 return false;
165 }
166 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000167 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700168 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800169 return false;
170 }
171 BitSet32 pointerIdBits;
172 for (size_t i = 0; i < pointerCount; i++) {
173 int32_t id = pointerProperties[i].id;
174 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700175 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
176 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800177 return false;
178 }
179 if (pointerIdBits.hasBit(id)) {
180 ALOGE("Motion event has duplicate pointer id %d", id);
181 return false;
182 }
183 pointerIdBits.markBit(id);
184 }
185 return true;
186}
187
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800188static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800189 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800190 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800191 return;
192 }
193
194 bool first = true;
195 Region::const_iterator cur = region.begin();
196 Region::const_iterator const tail = region.end();
197 while (cur != tail) {
198 if (first) {
199 first = false;
200 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800201 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800202 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800203 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 cur++;
205 }
206}
207
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700208/**
209 * Find the entry in std::unordered_map by key, and return it.
210 * If the entry is not found, return a default constructed entry.
211 *
212 * Useful when the entries are vectors, since an empty vector will be returned
213 * if the entry is not found.
214 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
215 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700216template <typename K, typename V>
217static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700218 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700219 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800220}
221
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700222/**
223 * Find the entry in std::unordered_map by value, and remove it.
224 * If more than one entry has the same value, then all matching
225 * key-value pairs will be removed.
226 *
227 * Return true if at least one value has been removed.
228 */
229template <typename K, typename V>
230static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
231 bool removed = false;
232 for (auto it = map.begin(); it != map.end();) {
233 if (it->second == value) {
234 it = map.erase(it);
235 removed = true;
236 } else {
237 it++;
238 }
239 }
240 return removed;
241}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800242
chaviwaf87b3e2019-10-01 16:59:28 -0700243static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
244 if (first == second) {
245 return true;
246 }
247
248 if (first == nullptr || second == nullptr) {
249 return false;
250 }
251
252 return first->getToken() == second->getToken();
253}
254
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800255static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
256 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
257}
258
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000259static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
260 EventEntry* eventEntry,
261 int32_t inputTargetFlags) {
262 if (inputTarget.useDefaultPointerInfo()) {
263 const PointerInfo& pointerInfo = inputTarget.getDefaultPointerInfo();
264 return std::make_unique<DispatchEntry>(eventEntry, // increments ref
265 inputTargetFlags, pointerInfo.xOffset,
266 pointerInfo.yOffset, inputTarget.globalScaleFactor,
267 pointerInfo.windowXScale, pointerInfo.windowYScale);
268 }
269
270 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
271 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
272
273 PointerCoords pointerCoords[motionEntry.pointerCount];
274
275 // Use the first pointer information to normalize all other pointers. This could be any pointer
276 // as long as all other pointers are normalized to the same value and the final DispatchEntry
277 // uses the offset and scale for the normalized pointer.
278 const PointerInfo& firstPointerInfo =
279 inputTarget.pointerInfos[inputTarget.pointerIds.firstMarkedBit()];
280
281 // Iterate through all pointers in the event to normalize against the first.
282 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
283 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
284 uint32_t pointerId = uint32_t(pointerProperties.id);
285 const PointerInfo& currPointerInfo = inputTarget.pointerInfos[pointerId];
286
287 // The scale factor is the ratio of the current pointers scale to the normalized scale.
288 float scaleXDiff = currPointerInfo.windowXScale / firstPointerInfo.windowXScale;
289 float scaleYDiff = currPointerInfo.windowYScale / firstPointerInfo.windowYScale;
290
291 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
292 // First apply the current pointers offset to set the window at 0,0
293 pointerCoords[pointerIndex].applyOffset(currPointerInfo.xOffset, currPointerInfo.yOffset);
294 // Next scale the coordinates.
295 pointerCoords[pointerIndex].scale(1, scaleXDiff, scaleYDiff);
296 // Lastly, offset the coordinates so they're in the normalized pointer's frame.
297 pointerCoords[pointerIndex].applyOffset(-firstPointerInfo.xOffset,
298 -firstPointerInfo.yOffset);
299 }
300
301 MotionEntry* combinedMotionEntry =
302 new MotionEntry(motionEntry.sequenceNum, motionEntry.eventTime, motionEntry.deviceId,
303 motionEntry.source, motionEntry.displayId, motionEntry.policyFlags,
304 motionEntry.action, motionEntry.actionButton, motionEntry.flags,
305 motionEntry.metaState, motionEntry.buttonState,
306 motionEntry.classification, motionEntry.edgeFlags,
307 motionEntry.xPrecision, motionEntry.yPrecision,
308 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
309 motionEntry.downTime, motionEntry.pointerCount,
310 motionEntry.pointerProperties, pointerCoords, 0 /* xOffset */,
311 0 /* yOffset */);
312
313 if (motionEntry.injectionState) {
314 combinedMotionEntry->injectionState = motionEntry.injectionState;
315 combinedMotionEntry->injectionState->refCount += 1;
316 }
317
318 std::unique_ptr<DispatchEntry> dispatchEntry =
319 std::make_unique<DispatchEntry>(combinedMotionEntry, // increments ref
320 inputTargetFlags, firstPointerInfo.xOffset,
321 firstPointerInfo.yOffset, inputTarget.globalScaleFactor,
322 firstPointerInfo.windowXScale,
323 firstPointerInfo.windowYScale);
324 combinedMotionEntry->release();
325 return dispatchEntry;
326}
327
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700328// --- InputDispatcherThread ---
329
330class InputDispatcher::InputDispatcherThread : public Thread {
331public:
332 explicit InputDispatcherThread(InputDispatcher* dispatcher)
333 : Thread(/* canCallJava */ true), mDispatcher(dispatcher) {}
334
335 ~InputDispatcherThread() {}
336
337private:
338 InputDispatcher* mDispatcher;
339
340 virtual bool threadLoop() override {
341 mDispatcher->dispatchOnce();
342 return true;
343 }
344};
345
Michael Wrightd02c5b62014-02-10 15:10:22 -0800346// --- InputDispatcher ---
347
Garfield Tan00f511d2019-06-12 16:55:40 -0700348InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
349 : mPolicy(policy),
350 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700351 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tan00f511d2019-06-12 16:55:40 -0700352 mAppSwitchSawKeyDown(false),
353 mAppSwitchDueTime(LONG_LONG_MAX),
354 mNextUnblockedEvent(nullptr),
355 mDispatchEnabled(false),
356 mDispatchFrozen(false),
357 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800358 // mInTouchMode will be initialized by the WindowManager to the default device config.
359 // To avoid leaking stack in case that call never comes, and for tests,
360 // initialize it here anyways.
361 mInTouchMode(true),
Garfield Tan00f511d2019-06-12 16:55:40 -0700362 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
363 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800364 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800365 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800366
Yi Kong9b14ac62018-07-17 13:48:38 -0700367 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800368
369 policy->getDispatcherConfiguration(&mConfig);
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700370
371 mThread = new InputDispatcherThread(this);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800372}
373
374InputDispatcher::~InputDispatcher() {
375 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800376 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800377
378 resetKeyRepeatLocked();
379 releasePendingEventLocked();
380 drainInboundQueueLocked();
381 }
382
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700383 while (!mConnectionsByFd.empty()) {
384 sp<Connection> connection = mConnectionsByFd.begin()->second;
385 unregisterInputChannel(connection->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800386 }
387}
388
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700389status_t InputDispatcher::start() {
390 if (mThread->isRunning()) {
391 return ALREADY_EXISTS;
392 }
393 return mThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
394}
395
396status_t InputDispatcher::stop() {
397 if (!mThread->isRunning()) {
398 return OK;
399 }
400 if (gettid() == mThread->getTid()) {
401 ALOGE("InputDispatcher can only be stopped from outside of the InputDispatcherThread!");
402 return INVALID_OPERATION;
403 }
404 // Directly calling requestExitAndWait() causes the thread to not exit
405 // if mLooper is waiting for a long timeout.
406 mThread->requestExit();
407 mLooper->wake();
408 return mThread->requestExitAndWait();
409}
410
Michael Wrightd02c5b62014-02-10 15:10:22 -0800411void InputDispatcher::dispatchOnce() {
412 nsecs_t nextWakeupTime = LONG_LONG_MAX;
413 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800414 std::scoped_lock _l(mLock);
415 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800416
417 // Run a dispatch loop if there are no pending commands.
418 // The dispatch loop might enqueue commands to run afterwards.
419 if (!haveCommandsLocked()) {
420 dispatchOnceInnerLocked(&nextWakeupTime);
421 }
422
423 // Run all pending commands if there are any.
424 // If any commands were run then force the next poll to wake up immediately.
425 if (runCommandsLockedInterruptible()) {
426 nextWakeupTime = LONG_LONG_MIN;
427 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800428
429 // We are about to enter an infinitely long sleep, because we have no commands or
430 // pending or queued events
431 if (nextWakeupTime == LONG_LONG_MAX) {
432 mDispatcherEnteredIdle.notify_all();
433 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800434 } // release lock
435
436 // Wait for callback or timeout or wake. (make sure we round up, not down)
437 nsecs_t currentTime = now();
438 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
439 mLooper->pollOnce(timeoutMillis);
440}
441
442void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
443 nsecs_t currentTime = now();
444
Jeff Browndc5992e2014-04-11 01:27:26 -0700445 // Reset the key repeat timer whenever normal dispatch is suspended while the
446 // device is in a non-interactive state. This is to ensure that we abort a key
447 // repeat if the device is just coming out of sleep.
448 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800449 resetKeyRepeatLocked();
450 }
451
452 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
453 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100454 if (DEBUG_FOCUS) {
455 ALOGD("Dispatch frozen. Waiting some more.");
456 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800457 return;
458 }
459
460 // Optimize latency of app switches.
461 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
462 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
463 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
464 if (mAppSwitchDueTime < *nextWakeupTime) {
465 *nextWakeupTime = mAppSwitchDueTime;
466 }
467
468 // Ready to start a new event.
469 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700470 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700471 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800472 if (isAppSwitchDue) {
473 // The inbound queue is empty so the app switch key we were waiting
474 // for will never arrive. Stop waiting for it.
475 resetPendingAppSwitchLocked(false);
476 isAppSwitchDue = false;
477 }
478
479 // Synthesize a key repeat if appropriate.
480 if (mKeyRepeatState.lastKeyEntry) {
481 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
482 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
483 } else {
484 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
485 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
486 }
487 }
488 }
489
490 // Nothing to do if there is no pending event.
491 if (!mPendingEvent) {
492 return;
493 }
494 } else {
495 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700496 mPendingEvent = mInboundQueue.front();
497 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800498 traceInboundQueueLengthLocked();
499 }
500
501 // Poke user activity for this event.
502 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700503 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800504 }
505
506 // Get ready to dispatch the event.
507 resetANRTimeoutsLocked();
508 }
509
510 // Now we have an event to dispatch.
511 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700512 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800513 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700514 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800515 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700516 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800517 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700518 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800519 }
520
521 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700522 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800523 }
524
525 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700526 case EventEntry::Type::CONFIGURATION_CHANGED: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700527 ConfigurationChangedEntry* typedEntry =
528 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
529 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700530 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700531 break;
532 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800533
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700534 case EventEntry::Type::DEVICE_RESET: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700535 DeviceResetEntry* typedEntry = static_cast<DeviceResetEntry*>(mPendingEvent);
536 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700537 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700538 break;
539 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800540
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100541 case EventEntry::Type::FOCUS: {
542 FocusEntry* typedEntry = static_cast<FocusEntry*>(mPendingEvent);
543 dispatchFocusLocked(currentTime, typedEntry);
544 done = true;
545 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
546 break;
547 }
548
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700549 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700550 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
551 if (isAppSwitchDue) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700552 if (isAppSwitchKeyEvent(*typedEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700553 resetPendingAppSwitchLocked(true);
554 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700555 } else if (dropReason == DropReason::NOT_DROPPED) {
556 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700557 }
558 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700559 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700560 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700561 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700562 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
563 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700564 }
565 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
566 break;
567 }
568
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700569 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700570 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700571 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
572 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800573 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700574 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700575 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700576 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700577 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
578 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700579 }
580 done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
581 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800582 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800583 }
584
585 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700586 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700587 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800588 }
Michael Wright3a981722015-06-10 15:26:13 +0100589 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800590
591 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700592 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800593 }
594}
595
596bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700597 bool needWake = mInboundQueue.empty();
598 mInboundQueue.push_back(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800599 traceInboundQueueLengthLocked();
600
601 switch (entry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700602 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700603 // Optimize app switch latency.
604 // If the application takes too long to catch up then we drop all events preceding
605 // the app switch key.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700606 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700607 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700608 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700609 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700610 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700611 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800612#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700613 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800614#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700615 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700616 mAppSwitchSawKeyDown = false;
617 needWake = true;
618 }
619 }
620 }
621 break;
622 }
623
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700624 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700625 // Optimize case where the current application is unresponsive and the user
626 // decides to touch a window in a different application.
627 // If the application takes too long to catch up then we drop all events preceding
628 // the touch into the other window.
629 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
630 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN &&
631 (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
632 mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY &&
633 mInputTargetWaitApplicationToken != nullptr) {
634 int32_t displayId = motionEntry->displayId;
635 int32_t x =
636 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
637 int32_t y =
638 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
639 sp<InputWindowHandle> touchedWindowHandle =
640 findTouchedWindowAtLocked(displayId, x, y);
641 if (touchedWindowHandle != nullptr &&
642 touchedWindowHandle->getApplicationToken() !=
643 mInputTargetWaitApplicationToken) {
644 // User touched a different application than the one we are waiting on.
645 // Flag the event, and start pruning the input queue.
646 mNextUnblockedEvent = motionEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800647 needWake = true;
648 }
649 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700650 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800651 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700652 case EventEntry::Type::CONFIGURATION_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100653 case EventEntry::Type::DEVICE_RESET:
654 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700655 // nothing to do
656 break;
657 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800658 }
659
660 return needWake;
661}
662
663void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
664 entry->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700665 mRecentQueue.push_back(entry);
666 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
667 mRecentQueue.front()->release();
668 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800669 }
670}
671
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700672sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
673 int32_t y, bool addOutsideTargets,
674 bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800675 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800676 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
677 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800678 const InputWindowInfo* windowInfo = windowHandle->getInfo();
679 if (windowInfo->displayId == displayId) {
680 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800681
682 if (windowInfo->visible) {
683 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700684 bool isTouchModal = (flags &
685 (InputWindowInfo::FLAG_NOT_FOCUSABLE |
686 InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800687 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800688 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700689 if (portalToDisplayId != ADISPLAY_ID_NONE &&
690 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800691 if (addPortalWindows) {
692 // For the monitoring channels of the display.
693 mTempTouchState.addPortalWindow(windowHandle);
694 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700695 return findTouchedWindowAtLocked(portalToDisplayId, x, y,
696 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800697 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800698 // Found window.
699 return windowHandle;
700 }
701 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800702
703 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700704 mTempTouchState.addOrUpdateWindow(windowHandle,
705 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
706 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800707 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800708 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800709 }
710 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700711 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800712}
713
Garfield Tane84e6f92019-08-29 17:28:41 -0700714std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +0000715 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
716 std::vector<TouchedMonitor> touchedMonitors;
717
718 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
719 addGestureMonitors(monitors, touchedMonitors);
720 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
721 const InputWindowInfo* windowInfo = portalWindow->getInfo();
722 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700723 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
724 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000725 }
726 return touchedMonitors;
727}
728
729void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700730 std::vector<TouchedMonitor>& outTouchedMonitors,
731 float xOffset, float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000732 if (monitors.empty()) {
733 return;
734 }
735 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
736 for (const Monitor& monitor : monitors) {
737 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
738 }
739}
740
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700741void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800742 const char* reason;
743 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700744 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800745#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700746 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800747#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700748 reason = "inbound event was dropped because the policy consumed it";
749 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700750 case DropReason::DISABLED:
751 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700752 ALOGI("Dropped event because input dispatch is disabled.");
753 }
754 reason = "inbound event was dropped because input dispatch is disabled";
755 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700756 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700757 ALOGI("Dropped event because of pending overdue app switch.");
758 reason = "inbound event was dropped because of pending overdue app switch";
759 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700760 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700761 ALOGI("Dropped event because the current application is not responding and the user "
762 "has started interacting with a different application.");
763 reason = "inbound event was dropped because the current application is not responding "
764 "and the user has started interacting with a different application";
765 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700766 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700767 ALOGI("Dropped event because it is stale.");
768 reason = "inbound event was dropped because it is stale";
769 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700770 case DropReason::NOT_DROPPED: {
771 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700772 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700773 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800774 }
775
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700776 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700777 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800778 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
779 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700780 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800781 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700782 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700783 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
784 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700785 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
786 synthesizeCancelationEventsForAllConnectionsLocked(options);
787 } else {
788 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
789 synthesizeCancelationEventsForAllConnectionsLocked(options);
790 }
791 break;
792 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100793 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700794 case EventEntry::Type::CONFIGURATION_CHANGED:
795 case EventEntry::Type::DEVICE_RESET: {
796 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
797 break;
798 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800799 }
800}
801
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800802static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700803 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
804 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800805}
806
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700807bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
808 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
809 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
810 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800811}
812
813bool InputDispatcher::isAppSwitchPendingLocked() {
814 return mAppSwitchDueTime != LONG_LONG_MAX;
815}
816
817void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
818 mAppSwitchDueTime = LONG_LONG_MAX;
819
820#if DEBUG_APP_SWITCH
821 if (handled) {
822 ALOGD("App switch has arrived.");
823 } else {
824 ALOGD("App switch was abandoned.");
825 }
826#endif
827}
828
Michael Wrightd02c5b62014-02-10 15:10:22 -0800829bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700830 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800831}
832
833bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700834 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800835 return false;
836 }
837
838 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700839 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700840 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800841 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700842 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800843
844 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700845 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800846 return true;
847}
848
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700849void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
850 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800851}
852
853void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700854 while (!mInboundQueue.empty()) {
855 EventEntry* entry = mInboundQueue.front();
856 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800857 releaseInboundEventLocked(entry);
858 }
859 traceInboundQueueLengthLocked();
860}
861
862void InputDispatcher::releasePendingEventLocked() {
863 if (mPendingEvent) {
864 resetANRTimeoutsLocked();
865 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700866 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800867 }
868}
869
870void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
871 InjectionState* injectionState = entry->injectionState;
872 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
873#if DEBUG_DISPATCH_CYCLE
874 ALOGD("Injected inbound event was dropped.");
875#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800876 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800877 }
878 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700879 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800880 }
881 addRecentEventLocked(entry);
882 entry->release();
883}
884
885void InputDispatcher::resetKeyRepeatLocked() {
886 if (mKeyRepeatState.lastKeyEntry) {
887 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700888 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800889 }
890}
891
Garfield Tane84e6f92019-08-29 17:28:41 -0700892KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800893 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
894
895 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700896 uint32_t policyFlags = entry->policyFlags &
897 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800898 if (entry->refCount == 1) {
899 entry->recycle();
900 entry->eventTime = currentTime;
901 entry->policyFlags = policyFlags;
902 entry->repeatCount += 1;
903 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700904 KeyEntry* newEntry =
905 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, entry->deviceId,
906 entry->source, entry->displayId, policyFlags, entry->action,
907 entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
908 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800909
910 mKeyRepeatState.lastKeyEntry = newEntry;
911 entry->release();
912
913 entry = newEntry;
914 }
915 entry->syntheticRepeat = true;
916
917 // Increment reference count since we keep a reference to the event in
918 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
919 entry->refCount += 1;
920
921 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
922 return entry;
923}
924
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700925bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
926 ConfigurationChangedEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800927#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700928 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800929#endif
930
931 // Reset key repeating in case a keyboard device was added or removed or something.
932 resetKeyRepeatLocked();
933
934 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700935 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
936 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800937 commandEntry->eventTime = entry->eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700938 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800939 return true;
940}
941
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700942bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceResetEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800943#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700944 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700945 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800946#endif
947
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700948 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800949 options.deviceId = entry->deviceId;
950 synthesizeCancelationEventsForAllConnectionsLocked(options);
951 return true;
952}
953
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100954void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) {
955 FocusEntry* focusEntry =
956 new FocusEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, now(), window.getToken(), hasFocus);
957 enqueueInboundEventLocked(focusEntry);
958}
959
960void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) {
961 sp<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
962 if (channel == nullptr) {
963 return; // Window has gone away
964 }
965 InputTarget target;
966 target.inputChannel = channel;
967 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
968 entry->dispatchInProgress = true;
969
970 dispatchEventLocked(currentTime, entry, {target});
971}
972
Michael Wrightd02c5b62014-02-10 15:10:22 -0800973bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700974 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800975 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700976 if (!entry->dispatchInProgress) {
977 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
978 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
979 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
980 if (mKeyRepeatState.lastKeyEntry &&
981 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800982 // We have seen two identical key downs in a row which indicates that the device
983 // driver is automatically generating key repeats itself. We take note of the
984 // repeat here, but we disable our own next key repeat timer since it is clear that
985 // we will not need to synthesize key repeats ourselves.
986 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
987 resetKeyRepeatLocked();
988 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
989 } else {
990 // Not a repeat. Save key down state in case we do see a repeat later.
991 resetKeyRepeatLocked();
992 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
993 }
994 mKeyRepeatState.lastKeyEntry = entry;
995 entry->refCount += 1;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700996 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800997 resetKeyRepeatLocked();
998 }
999
1000 if (entry->repeatCount == 1) {
1001 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1002 } else {
1003 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1004 }
1005
1006 entry->dispatchInProgress = true;
1007
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001008 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001009 }
1010
1011 // Handle case where the policy asked us to try again later last time.
1012 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1013 if (currentTime < entry->interceptKeyWakeupTime) {
1014 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1015 *nextWakeupTime = entry->interceptKeyWakeupTime;
1016 }
1017 return false; // wait until next wakeup
1018 }
1019 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1020 entry->interceptKeyWakeupTime = 0;
1021 }
1022
1023 // Give the policy a chance to intercept the key.
1024 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1025 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001026 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001027 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +08001028 sp<InputWindowHandle> focusedWindowHandle =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001029 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(*entry));
Tiger Huang721e26f2018-07-24 22:26:19 +08001030 if (focusedWindowHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001031 commandEntry->inputChannel = getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001032 }
1033 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001034 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001035 entry->refCount += 1;
1036 return false; // wait for the command to run
1037 } else {
1038 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1039 }
1040 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001041 if (*dropReason == DropReason::NOT_DROPPED) {
1042 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001043 }
1044 }
1045
1046 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001047 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001048 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001049 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001050 : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08001051 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001052 return true;
1053 }
1054
1055 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001056 std::vector<InputTarget> inputTargets;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001057 int32_t injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001058 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001059 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1060 return false;
1061 }
1062
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001063 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001064 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
1065 return true;
1066 }
1067
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001068 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001069 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001070
1071 // Dispatch the key.
1072 dispatchEventLocked(currentTime, entry, inputTargets);
1073 return true;
1074}
1075
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001076void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001077#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001078 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001079 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1080 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001081 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1082 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1083 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001084#endif
1085}
1086
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001087bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry,
1088 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001089 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001090 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001091 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001092 entry->dispatchInProgress = true;
1093
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001094 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001095 }
1096
1097 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001098 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001099 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001100 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001101 : INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001102 return true;
1103 }
1104
1105 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1106
1107 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001108 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001109
1110 bool conflictingPointerActions = false;
1111 int32_t injectionResult;
1112 if (isPointerEvent) {
1113 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001114 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001115 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001116 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001117 } else {
1118 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001119 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001120 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001121 }
1122 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1123 return false;
1124 }
1125
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001126 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001127 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001128 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001129 CancelationOptions::Mode mode(isPointerEvent
1130 ? CancelationOptions::CANCEL_POINTER_EVENTS
1131 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001132 CancelationOptions options(mode, "input event injection failed");
1133 synthesizeCancelationEventsForMonitorsLocked(options);
1134 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001135 return true;
1136 }
1137
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001138 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001139 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001140
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001141 if (isPointerEvent) {
1142 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1143 if (stateIndex >= 0) {
1144 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001145 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001146 // The event has gone through these portal windows, so we add monitoring targets of
1147 // the corresponding displays as well.
1148 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001149 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001150 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001151 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001152 }
1153 }
1154 }
1155 }
1156
Michael Wrightd02c5b62014-02-10 15:10:22 -08001157 // Dispatch the motion.
1158 if (conflictingPointerActions) {
1159 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001160 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001161 synthesizeCancelationEventsForAllConnectionsLocked(options);
1162 }
1163 dispatchEventLocked(currentTime, entry, inputTargets);
1164 return true;
1165}
1166
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001167void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001168#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001169 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001170 ", policyFlags=0x%x, "
1171 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1172 "metaState=0x%x, buttonState=0x%x,"
1173 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001174 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1175 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1176 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001177
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001178 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001179 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001180 "x=%f, y=%f, pressure=%f, size=%f, "
1181 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1182 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001183 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1184 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1185 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1186 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1187 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1188 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1189 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1190 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1191 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1192 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001193 }
1194#endif
1195}
1196
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001197void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* eventEntry,
1198 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001199 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001200#if DEBUG_DISPATCH_CYCLE
1201 ALOGD("dispatchEventToCurrentInputTargets");
1202#endif
1203
1204 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1205
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001206 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001207
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001208 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001209 sp<Connection> connection =
1210 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001211 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001212 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001213 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001214 if (DEBUG_FOCUS) {
1215 ALOGD("Dropping event delivery to target with channel '%s' because it "
1216 "is no longer registered with the input dispatcher.",
1217 inputTarget.inputChannel->getName().c_str());
1218 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001219 }
1220 }
1221}
1222
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001223int32_t InputDispatcher::handleTargetsNotReadyLocked(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001224 nsecs_t currentTime, const EventEntry& entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001225 const sp<InputApplicationHandle>& applicationHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001226 const sp<InputWindowHandle>& windowHandle, nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001227 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001228 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001229 if (DEBUG_FOCUS) {
1230 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1231 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001232 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1233 mInputTargetWaitStartTime = currentTime;
1234 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1235 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001236 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001237 }
1238 } else {
1239 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001240 if (DEBUG_FOCUS) {
1241 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
1242 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), reason);
1243 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001244 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001245 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001246 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001247 } else if (applicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001248 timeout =
1249 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001250 } else {
1251 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1252 }
1253
1254 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1255 mInputTargetWaitStartTime = currentTime;
1256 mInputTargetWaitTimeoutTime = currentTime + timeout;
1257 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001258 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001259
Yi Kong9b14ac62018-07-17 13:48:38 -07001260 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001261 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001262 }
Robert Carr740167f2018-10-11 19:03:41 -07001263 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1264 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001265 }
1266 }
1267 }
1268
1269 if (mInputTargetWaitTimeoutExpired) {
1270 return INPUT_EVENT_INJECTION_TIMED_OUT;
1271 }
1272
1273 if (currentTime >= mInputTargetWaitTimeoutTime) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001274 onANRLocked(currentTime, applicationHandle, windowHandle, entry.eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001275 mInputTargetWaitStartTime, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001276
1277 // Force poll loop to wake up immediately on next iteration once we get the
1278 // ANR response back from the policy.
1279 *nextWakeupTime = LONG_LONG_MIN;
1280 return INPUT_EVENT_INJECTION_PENDING;
1281 } else {
1282 // Force poll loop to wake up when timeout is due.
1283 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1284 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1285 }
1286 return INPUT_EVENT_INJECTION_PENDING;
1287 }
1288}
1289
Robert Carr803535b2018-08-02 16:38:15 -07001290void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1291 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1292 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1293 state.removeWindowByToken(token);
1294 }
1295}
1296
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001297void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001298 nsecs_t newTimeout, const sp<IBinder>& inputConnectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001299 if (newTimeout > 0) {
1300 // Extend the timeout.
1301 mInputTargetWaitTimeoutTime = now() + newTimeout;
1302 } else {
1303 // Give up.
1304 mInputTargetWaitTimeoutExpired = true;
1305
1306 // Input state will not be realistic. Mark it out of sync.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001307 sp<Connection> connection = getConnectionLocked(inputConnectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001308 if (connection != nullptr) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001309 removeWindowByTokenLocked(inputConnectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001310
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001311 if (connection->status == Connection::STATUS_NORMAL) {
1312 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1313 "application not responding");
1314 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001315 }
1316 }
1317 }
1318}
1319
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001320nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001321 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1322 return currentTime - mInputTargetWaitStartTime;
1323 }
1324 return 0;
1325}
1326
1327void InputDispatcher::resetANRTimeoutsLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001328 if (DEBUG_FOCUS) {
1329 ALOGD("Resetting ANR timeouts.");
1330 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001331
1332 // Reset input target wait timeout.
1333 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001334 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001335}
1336
Tiger Huang721e26f2018-07-24 22:26:19 +08001337/**
1338 * Get the display id that the given event should go to. If this event specifies a valid display id,
1339 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1340 * Focused display is the display that the user most recently interacted with.
1341 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001342int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001343 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001344 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001345 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001346 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1347 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001348 break;
1349 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001350 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001351 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1352 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001353 break;
1354 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001355 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001356 case EventEntry::Type::CONFIGURATION_CHANGED:
1357 case EventEntry::Type::DEVICE_RESET: {
1358 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001359 return ADISPLAY_ID_NONE;
1360 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001361 }
1362 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1363}
1364
Michael Wrightd02c5b62014-02-10 15:10:22 -08001365int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001366 const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001367 std::vector<InputTarget>& inputTargets,
1368 nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001369 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001370 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001371
Tiger Huang721e26f2018-07-24 22:26:19 +08001372 int32_t displayId = getTargetDisplayId(entry);
1373 sp<InputWindowHandle> focusedWindowHandle =
1374 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1375 sp<InputApplicationHandle> focusedApplicationHandle =
1376 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1377
Michael Wrightd02c5b62014-02-10 15:10:22 -08001378 // If there is no currently focused window and no focused application
1379 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001380 if (focusedWindowHandle == nullptr) {
1381 if (focusedApplicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001382 injectionResult =
1383 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1384 nullptr, nextWakeupTime,
1385 "Waiting because no window has focus but there is "
1386 "a focused application that may eventually add a "
1387 "window when it finishes starting up.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001388 goto Unresponsive;
1389 }
1390
Arthur Hung3b413f22018-10-26 18:05:34 +08001391 ALOGI("Dropping event because there is no focused window or focused application in display "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001392 "%" PRId32 ".",
1393 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001394 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1395 goto Failed;
1396 }
1397
1398 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001399 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001400 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1401 goto Failed;
1402 }
1403
Jeff Brownffb49772014-10-10 19:01:34 -07001404 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001405 reason = checkWindowReadyForMoreInputLocked(currentTime, focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001406 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001407 injectionResult =
1408 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1409 focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001410 goto Unresponsive;
1411 }
1412
1413 // Success! Output targets.
1414 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001415 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001416 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1417 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001418
1419 // Done.
1420Failed:
1421Unresponsive:
1422 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001423 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001424 if (DEBUG_FOCUS) {
1425 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1426 "timeSpentWaitingForApplication=%0.1fms",
1427 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1428 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001429 return injectionResult;
1430}
1431
1432int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001433 const MotionEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001434 std::vector<InputTarget>& inputTargets,
1435 nsecs_t* nextWakeupTime,
1436 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001437 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001438 enum InjectionPermission {
1439 INJECTION_PERMISSION_UNKNOWN,
1440 INJECTION_PERMISSION_GRANTED,
1441 INJECTION_PERMISSION_DENIED
1442 };
1443
Michael Wrightd02c5b62014-02-10 15:10:22 -08001444 // For security reasons, we defer updating the touch state until we are sure that
1445 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001446 int32_t displayId = entry.displayId;
1447 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001448 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1449
1450 // Update the touch state as needed based on the properties of the touch event.
1451 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1452 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1453 sp<InputWindowHandle> newHoverWindowHandle;
1454
Jeff Brownf086ddb2014-02-11 14:28:48 -08001455 // Copy current touch state into mTempTouchState.
1456 // This state is always reset at the end of this function, so if we don't find state
1457 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001458 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001459 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1460 if (oldStateIndex >= 0) {
1461 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1462 mTempTouchState.copyFrom(*oldState);
1463 }
1464
1465 bool isSplit = mTempTouchState.split;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001466 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0 &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001467 (mTempTouchState.deviceId != entry.deviceId || mTempTouchState.source != entry.source ||
1468 mTempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001469 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1470 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1471 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1472 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1473 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001474 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001475 bool wrongDevice = false;
1476 if (newGesture) {
1477 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001478 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001479 if (DEBUG_FOCUS) {
1480 ALOGD("Dropping event because a pointer for a different device is already down "
1481 "in display %" PRId32,
1482 displayId);
1483 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001484 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001485 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1486 switchedDevice = false;
1487 wrongDevice = true;
1488 goto Failed;
1489 }
1490 mTempTouchState.reset();
1491 mTempTouchState.down = down;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001492 mTempTouchState.deviceId = entry.deviceId;
1493 mTempTouchState.source = entry.source;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001494 mTempTouchState.displayId = displayId;
1495 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001496 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001497 if (DEBUG_FOCUS) {
1498 ALOGI("Dropping move event because a pointer for a different device is already active "
1499 "in display %" PRId32,
1500 displayId);
1501 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001502 // TODO: test multiple simultaneous input streams.
1503 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1504 switchedDevice = false;
1505 wrongDevice = true;
1506 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001507 }
1508
1509 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1510 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1511
Garfield Tan00f511d2019-06-12 16:55:40 -07001512 int32_t x;
1513 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001514 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001515 // Always dispatch mouse events to cursor position.
1516 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001517 x = int32_t(entry.xCursorPosition);
1518 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001519 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001520 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1521 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001522 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001523 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001524 sp<InputWindowHandle> newTouchedWindowHandle =
1525 findTouchedWindowAtLocked(displayId, x, y, isDown /*addOutsideTargets*/,
1526 true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001527
1528 std::vector<TouchedMonitor> newGestureMonitors = isDown
1529 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1530 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001531
Michael Wrightd02c5b62014-02-10 15:10:22 -08001532 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001533 if (newTouchedWindowHandle != nullptr &&
1534 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001535 // New window supports splitting, but we should never split mouse events.
1536 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001537 } else if (isSplit) {
1538 // New window does not support splitting but we have already split events.
1539 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001540 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001541 }
1542
1543 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001544 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001545 // Try to assign the pointer to the first foreground window we find, if there is one.
1546 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001547 }
1548
1549 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1550 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001551 "(%d, %d) in display %" PRId32 ".",
1552 x, y, displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00001553 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1554 goto Failed;
1555 }
1556
1557 if (newTouchedWindowHandle != nullptr) {
1558 // Set target flags.
1559 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1560 if (isSplit) {
1561 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001562 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001563 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1564 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1565 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1566 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1567 }
1568
1569 // Update hover state.
1570 if (isHoverAction) {
1571 newHoverWindowHandle = newTouchedWindowHandle;
1572 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1573 newHoverWindowHandle = mLastHoverWindowHandle;
1574 }
1575
1576 // Update the temporary touch state.
1577 BitSet32 pointerIds;
1578 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001579 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001580 pointerIds.markBit(pointerId);
1581 }
1582 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001583 }
1584
Michael Wright3dd60e22019-03-27 22:06:44 +00001585 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001586 } else {
1587 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1588
1589 // If the pointer is not currently down, then ignore the event.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001590 if (!mTempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001591 if (DEBUG_FOCUS) {
1592 ALOGD("Dropping event because the pointer is not down or we previously "
1593 "dropped the pointer down event in display %" PRId32,
1594 displayId);
1595 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001596 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1597 goto Failed;
1598 }
1599
1600 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001601 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001602 mTempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001603 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1604 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605
1606 sp<InputWindowHandle> oldTouchedWindowHandle =
1607 mTempTouchState.getFirstForegroundWindowHandle();
1608 sp<InputWindowHandle> newTouchedWindowHandle =
1609 findTouchedWindowAtLocked(displayId, x, y);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001610 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1611 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001612 if (DEBUG_FOCUS) {
1613 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1614 oldTouchedWindowHandle->getName().c_str(),
1615 newTouchedWindowHandle->getName().c_str(), displayId);
1616 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001617 // Make a slippery exit from the old window.
1618 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001619 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1620 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001621
1622 // Make a slippery entrance into the new window.
1623 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1624 isSplit = true;
1625 }
1626
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001627 int32_t targetFlags =
1628 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001629 if (isSplit) {
1630 targetFlags |= InputTarget::FLAG_SPLIT;
1631 }
1632 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1633 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1634 }
1635
1636 BitSet32 pointerIds;
1637 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001638 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001639 }
1640 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1641 }
1642 }
1643 }
1644
1645 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1646 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001647 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001648#if DEBUG_HOVER
1649 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001650 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001651#endif
1652 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001653 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT,
1654 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001655 }
1656
1657 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001658 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001659#if DEBUG_HOVER
1660 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001661 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001662#endif
1663 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001664 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1665 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001666 }
1667 }
1668
1669 // Check permission to inject into all touched foreground windows and ensure there
1670 // is at least one touched foreground window.
1671 {
1672 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001673 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001674 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1675 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001676 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001677 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1678 injectionPermission = INJECTION_PERMISSION_DENIED;
1679 goto Failed;
1680 }
1681 }
1682 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001683 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1684 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001685 if (DEBUG_FOCUS) {
1686 ALOGD("Dropping event because there is no touched foreground window in display "
1687 "%" PRId32 " or gesture monitor to receive it.",
1688 displayId);
1689 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001690 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1691 goto Failed;
1692 }
1693
1694 // Permission granted to injection into all touched foreground windows.
1695 injectionPermission = INJECTION_PERMISSION_GRANTED;
1696 }
1697
1698 // Check whether windows listening for outside touches are owned by the same UID. If it is
1699 // set the policy flag that we will not reveal coordinate information to this window.
1700 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1701 sp<InputWindowHandle> foregroundWindowHandle =
1702 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001703 if (foregroundWindowHandle) {
1704 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1705 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1706 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1707 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1708 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1709 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001710 InputTarget::FLAG_ZERO_COORDS,
1711 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001712 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001713 }
1714 }
1715 }
1716 }
1717
1718 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001719 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001720 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001721 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001722 std::string reason =
1723 checkWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle,
1724 entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001725 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001726 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, nullptr,
1727 touchedWindow.windowHandle,
1728 nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001729 goto Unresponsive;
1730 }
1731 }
1732 }
1733
1734 // If this is the first pointer going down and the touched window has a wallpaper
1735 // then also add the touched wallpaper windows so they are locked in for the duration
1736 // of the touch gesture.
1737 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1738 // engine only supports touch events. We would need to add a mechanism similar
1739 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1740 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1741 sp<InputWindowHandle> foregroundWindowHandle =
1742 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001743 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001744 const std::vector<sp<InputWindowHandle>> windowHandles =
1745 getWindowHandlesLocked(displayId);
1746 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001747 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001748 if (info->displayId == displayId &&
1749 windowHandle->getInfo()->layoutParamsType == InputWindowInfo::TYPE_WALLPAPER) {
1750 mTempTouchState
1751 .addOrUpdateWindow(windowHandle,
1752 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1753 InputTarget::
1754 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1755 InputTarget::FLAG_DISPATCH_AS_IS,
1756 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001757 }
1758 }
1759 }
1760 }
1761
1762 // Success! Output targets.
1763 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1764
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001765 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001766 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001767 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001768 }
1769
Michael Wright3dd60e22019-03-27 22:06:44 +00001770 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1771 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001772 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00001773 }
1774
Michael Wrightd02c5b62014-02-10 15:10:22 -08001775 // Drop the outside or hover touch windows since we will not care about them
1776 // in the next iteration.
1777 mTempTouchState.filterNonAsIsTouchWindows();
1778
1779Failed:
1780 // Check injection permission once and for all.
1781 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001782 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001783 injectionPermission = INJECTION_PERMISSION_GRANTED;
1784 } else {
1785 injectionPermission = INJECTION_PERMISSION_DENIED;
1786 }
1787 }
1788
1789 // Update final pieces of touch state if the injector had permission.
1790 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1791 if (!wrongDevice) {
1792 if (switchedDevice) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001793 if (DEBUG_FOCUS) {
1794 ALOGD("Conflicting pointer actions: Switched to a different device.");
1795 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001796 *outConflictingPointerActions = true;
1797 }
1798
1799 if (isHoverAction) {
1800 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001801 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001802 if (DEBUG_FOCUS) {
1803 ALOGD("Conflicting pointer actions: Hover received while pointer was "
1804 "down.");
1805 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001806 *outConflictingPointerActions = true;
1807 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001808 mTempTouchState.reset();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001809 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1810 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001811 mTempTouchState.deviceId = entry.deviceId;
1812 mTempTouchState.source = entry.source;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001813 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001814 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001815 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
1816 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001817 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001818 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001819 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1820 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001821 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001822 if (DEBUG_FOCUS) {
1823 ALOGD("Conflicting pointer actions: Down received while already down.");
1824 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001825 *outConflictingPointerActions = true;
1826 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001827 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1828 // One pointer went up.
1829 if (isSplit) {
1830 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001831 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001832
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001833 for (size_t i = 0; i < mTempTouchState.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001834 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001835 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1836 touchedWindow.pointerIds.clearBit(pointerId);
1837 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001838 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001839 continue;
1840 }
1841 }
1842 i += 1;
1843 }
1844 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001845 }
1846
1847 // Save changes unless the action was scroll in which case the temporary touch
1848 // state was only valid for this one action.
1849 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1850 if (mTempTouchState.displayId >= 0) {
1851 if (oldStateIndex >= 0) {
1852 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1853 } else {
1854 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1855 }
1856 } else if (oldStateIndex >= 0) {
1857 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1858 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001859 }
1860
1861 // Update hover state.
1862 mLastHoverWindowHandle = newHoverWindowHandle;
1863 }
1864 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001865 if (DEBUG_FOCUS) {
1866 ALOGD("Not updating touch focus because injection was denied.");
1867 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001868 }
1869
1870Unresponsive:
1871 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1872 mTempTouchState.reset();
1873
1874 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001875 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001876 if (DEBUG_FOCUS) {
1877 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1878 "timeSpentWaitingForApplication=%0.1fms",
1879 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1880 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001881 return injectionResult;
1882}
1883
1884void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001885 int32_t targetFlags, BitSet32 pointerIds,
1886 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001887 std::vector<InputTarget>::iterator it =
1888 std::find_if(inputTargets.begin(), inputTargets.end(),
1889 [&windowHandle](const InputTarget& inputTarget) {
1890 return inputTarget.inputChannel->getConnectionToken() ==
1891 windowHandle->getToken();
1892 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00001893
Chavi Weingarten114b77f2020-01-15 22:35:10 +00001894 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001895
1896 if (it == inputTargets.end()) {
1897 InputTarget inputTarget;
1898 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1899 if (inputChannel == nullptr) {
1900 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1901 return;
1902 }
1903 inputTarget.inputChannel = inputChannel;
1904 inputTarget.flags = targetFlags;
1905 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
1906 inputTargets.push_back(inputTarget);
1907 it = inputTargets.end() - 1;
1908 }
1909
1910 ALOG_ASSERT(it->flags == targetFlags);
1911 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
1912
1913 it->addPointers(pointerIds, -windowInfo->frameLeft, -windowInfo->frameTop,
1914 windowInfo->windowXScale, windowInfo->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001915}
1916
Michael Wright3dd60e22019-03-27 22:06:44 +00001917void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001918 int32_t displayId, float xOffset,
1919 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001920 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1921 mGlobalMonitorsByDisplay.find(displayId);
1922
1923 if (it != mGlobalMonitorsByDisplay.end()) {
1924 const std::vector<Monitor>& monitors = it->second;
1925 for (const Monitor& monitor : monitors) {
1926 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001927 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001928 }
1929}
1930
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001931void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
1932 float yOffset,
1933 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001934 InputTarget target;
1935 target.inputChannel = monitor.inputChannel;
1936 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001937 target.setDefaultPointerInfo(xOffset, yOffset, 1 /* windowXScale */, 1 /* windowYScale */);
Michael Wright3dd60e22019-03-27 22:06:44 +00001938 inputTargets.push_back(target);
1939}
1940
Michael Wrightd02c5b62014-02-10 15:10:22 -08001941bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001942 const InjectionState* injectionState) {
1943 if (injectionState &&
1944 (windowHandle == nullptr ||
1945 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
1946 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001947 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001948 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001949 "owned by uid %d",
1950 injectionState->injectorPid, injectionState->injectorUid,
1951 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001952 } else {
1953 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001954 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001955 }
1956 return false;
1957 }
1958 return true;
1959}
1960
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001961bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
1962 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001963 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001964 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1965 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001966 if (otherHandle == windowHandle) {
1967 break;
1968 }
1969
1970 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001971 if (otherInfo->displayId == displayId && otherInfo->visible &&
1972 !otherInfo->isTrustedOverlay() && otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001973 return true;
1974 }
1975 }
1976 return false;
1977}
1978
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001979bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1980 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001981 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001982 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001983 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001984 if (otherHandle == windowHandle) {
1985 break;
1986 }
1987
1988 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001989 if (otherInfo->displayId == displayId && otherInfo->visible &&
1990 !otherInfo->isTrustedOverlay() && otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001991 return true;
1992 }
1993 }
1994 return false;
1995}
1996
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001997std::string InputDispatcher::checkWindowReadyForMoreInputLocked(
1998 nsecs_t currentTime, const sp<InputWindowHandle>& windowHandle,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001999 const EventEntry& eventEntry, const char* targetType) {
Jeff Brownffb49772014-10-10 19:01:34 -07002000 // If the window is paused then keep waiting.
2001 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002002 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07002003 }
2004
2005 // If the window's connection is not registered then keep waiting.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07002006 sp<Connection> connection = getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002007 if (connection == nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002008 return StringPrintf("Waiting because the %s window's input channel is not "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002009 "registered with the input dispatcher. The window may be in the "
2010 "process of being removed.",
2011 targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07002012 }
2013
2014 // If the connection is dead then keep waiting.
Jeff Brownffb49772014-10-10 19:01:34 -07002015 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002016 return StringPrintf("Waiting because the %s window's input connection is %s."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002017 "The window may be in the process of being removed.",
2018 targetType, connection->getStatusLabel());
Jeff Brownffb49772014-10-10 19:01:34 -07002019 }
2020
2021 // If the connection is backed up then keep waiting.
2022 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002023 return StringPrintf("Waiting because the %s window's input channel is full. "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002024 "Outbound queue length: %zu. Wait queue length: %zu.",
2025 targetType, connection->outboundQueue.size(),
2026 connection->waitQueue.size());
Jeff Brownffb49772014-10-10 19:01:34 -07002027 }
2028
2029 // Ensure that the dispatch queues aren't too far backed up for this event.
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002030 if (eventEntry.type == EventEntry::Type::KEY) {
Jeff Brownffb49772014-10-10 19:01:34 -07002031 // If the event is a key event, then we must wait for all previous events to
2032 // complete before delivering it because previous events may have the
2033 // side-effect of transferring focus to a different window and we want to
2034 // ensure that the following keys are sent to the new window.
2035 //
2036 // Suppose the user touches a button in a window then immediately presses "A".
2037 // If the button causes a pop-up window to appear then we want to ensure that
2038 // the "A" key is delivered to the new pop-up window. This is because users
2039 // often anticipate pending UI changes when typing on a keyboard.
2040 // To obtain this behavior, we must serialize key events with respect to all
2041 // prior input events.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002042 if (!connection->outboundQueue.empty() || !connection->waitQueue.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002043 return StringPrintf("Waiting to send key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002044 "finished processing all of the input events that were previously "
2045 "delivered to it. Outbound queue length: %zu. Wait queue length: "
2046 "%zu.",
2047 targetType, connection->outboundQueue.size(),
2048 connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002049 }
Jeff Brownffb49772014-10-10 19:01:34 -07002050 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002051 // Touch events can always be sent to a window immediately because the user intended
2052 // to touch whatever was visible at the time. Even if focus changes or a new
2053 // window appears moments later, the touch event was meant to be delivered to
2054 // whatever window happened to be on screen at the time.
2055 //
2056 // Generic motion events, such as trackball or joystick events are a little trickier.
2057 // Like key events, generic motion events are delivered to the focused window.
2058 // Unlike key events, generic motion events don't tend to transfer focus to other
2059 // windows and it is not important for them to be serialized. So we prefer to deliver
2060 // generic motion events as soon as possible to improve efficiency and reduce lag
2061 // through batching.
2062 //
2063 // The one case where we pause input event delivery is when the wait queue is piling
2064 // up with lots of events because the application is not responding.
2065 // This condition ensures that ANRs are detected reliably.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002066 if (!connection->waitQueue.empty() &&
2067 currentTime >=
2068 connection->waitQueue.front()->deliveryTime + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002069 return StringPrintf("Waiting to send non-key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002070 "finished processing certain input events that were delivered to "
2071 "it over "
2072 "%0.1fms ago. Wait queue length: %zu. Wait queue head age: "
2073 "%0.1fms.",
2074 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
2075 connection->waitQueue.size(),
2076 (currentTime - connection->waitQueue.front()->deliveryTime) *
2077 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002078 }
2079 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002080 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002081}
2082
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002083std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002084 const sp<InputApplicationHandle>& applicationHandle,
2085 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002086 if (applicationHandle != nullptr) {
2087 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002088 std::string label(applicationHandle->getName());
2089 label += " - ";
2090 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002091 return label;
2092 } else {
2093 return applicationHandle->getName();
2094 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002095 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002096 return windowHandle->getName();
2097 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002098 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002099 }
2100}
2101
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002102void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002103 if (eventEntry.type == EventEntry::Type::FOCUS) {
2104 // Focus events are passed to apps, but do not represent user activity.
2105 return;
2106 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002107 int32_t displayId = getTargetDisplayId(eventEntry);
2108 sp<InputWindowHandle> focusedWindowHandle =
2109 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
2110 if (focusedWindowHandle != nullptr) {
2111 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002112 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
2113#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002114 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002115#endif
2116 return;
2117 }
2118 }
2119
2120 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002121 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002122 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002123 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2124 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002125 return;
2126 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002127
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002128 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002129 eventType = USER_ACTIVITY_EVENT_TOUCH;
2130 }
2131 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002132 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002133 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002134 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2135 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002136 return;
2137 }
2138 eventType = USER_ACTIVITY_EVENT_BUTTON;
2139 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002140 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002141 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002142 case EventEntry::Type::CONFIGURATION_CHANGED:
2143 case EventEntry::Type::DEVICE_RESET: {
2144 LOG_ALWAYS_FATAL("%s events are not user activity",
2145 EventEntry::typeToString(eventEntry.type));
2146 break;
2147 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002148 }
2149
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002150 std::unique_ptr<CommandEntry> commandEntry =
2151 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002152 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002153 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002154 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002155}
2156
2157void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002158 const sp<Connection>& connection,
2159 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002160 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002161 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002162 std::string message =
2163 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2164 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002165 ATRACE_NAME(message.c_str());
2166 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002167#if DEBUG_DISPATCH_CYCLE
2168 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002169 "globalScaleFactor=%f, pointerIds=0x%x %s",
2170 connection->getInputChannelName().c_str(), inputTarget.flags,
2171 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2172 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002173#endif
2174
2175 // Skip this event if the connection status is not normal.
2176 // We don't want to enqueue additional outbound events if the connection is broken.
2177 if (connection->status != Connection::STATUS_NORMAL) {
2178#if DEBUG_DISPATCH_CYCLE
2179 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002180 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002181#endif
2182 return;
2183 }
2184
2185 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002186 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2187 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2188 "Entry type %s should not have FLAG_SPLIT",
2189 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002190
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002191 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002192 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002193 MotionEntry* splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002194 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002195 if (!splitMotionEntry) {
2196 return; // split event was dropped
2197 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002198 if (DEBUG_FOCUS) {
2199 ALOGD("channel '%s' ~ Split motion event.",
2200 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002201 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002202 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002203 enqueueDispatchEntriesLocked(currentTime, connection, splitMotionEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002204 splitMotionEntry->release();
2205 return;
2206 }
2207 }
2208
2209 // Not splitting. Enqueue dispatch entries for the event as is.
2210 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2211}
2212
2213void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002214 const sp<Connection>& connection,
2215 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002216 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002217 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002218 std::string message =
2219 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32
2220 ")",
2221 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002222 ATRACE_NAME(message.c_str());
2223 }
2224
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002225 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002226
2227 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002228 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002229 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002230 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002231 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002232 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002233 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002234 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002235 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002236 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002237 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002238 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002239 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002240
2241 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002242 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002243 startDispatchCycleLocked(currentTime, connection);
2244 }
2245}
2246
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002247void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
2248 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002249 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002250 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002251 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002252 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2253 connection->getInputChannelName().c_str(),
2254 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002255 ATRACE_NAME(message.c_str());
2256 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002257 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002258 if (!(inputTargetFlags & dispatchMode)) {
2259 return;
2260 }
2261 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2262
2263 // This is a new event.
2264 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002265 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002266 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002267
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002268 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2269 // different EventEntry than what was passed in.
2270 EventEntry* newEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002271 // Apply target flags and update the connection's input state.
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002272 switch (newEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002273 case EventEntry::Type::KEY: {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002274 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*newEntry);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002275 dispatchEntry->resolvedAction = keyEntry.action;
2276 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002277
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002278 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2279 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002280#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002281 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2282 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002283#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002284 return; // skip the inconsistent event
2285 }
2286 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002287 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002288
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002289 case EventEntry::Type::MOTION: {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002290 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*newEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002291 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2292 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2293 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2294 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2295 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2296 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2297 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2298 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2299 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2300 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2301 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002302 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002303 }
2304 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002305 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2306 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002307#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002308 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2309 "event",
2310 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002311#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002312 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2313 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002314
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002315 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002316 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2317 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2318 }
2319 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2320 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2321 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002322
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002323 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2324 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002325#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002326 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2327 "event",
2328 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002329#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002330 return; // skip the inconsistent event
2331 }
2332
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002333 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002334 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002335
2336 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002337 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002338 case EventEntry::Type::FOCUS: {
2339 break;
2340 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002341 case EventEntry::Type::CONFIGURATION_CHANGED:
2342 case EventEntry::Type::DEVICE_RESET: {
2343 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002344 EventEntry::typeToString(newEntry->type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002345 break;
2346 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002347 }
2348
2349 // Remember that we are waiting for this dispatch to complete.
2350 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002351 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002352 }
2353
2354 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002355 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002356 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002357}
2358
chaviwfd6d3512019-03-25 13:23:49 -07002359void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002360 const sp<IBinder>& newToken) {
chaviw8c9cf542019-03-25 13:02:48 -07002361 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002362 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2363 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002364 return;
2365 }
2366
2367 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2368 if (inputWindowHandle == nullptr) {
2369 return;
2370 }
2371
chaviw8c9cf542019-03-25 13:02:48 -07002372 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002373 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002374
2375 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2376
2377 if (!hasFocusChanged) {
2378 return;
2379 }
2380
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002381 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2382 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002383 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002384 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002385}
2386
2387void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002388 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002389 if (ATRACE_ENABLED()) {
2390 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002391 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002392 ATRACE_NAME(message.c_str());
2393 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002394#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002395 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002396#endif
2397
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002398 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2399 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002400 dispatchEntry->deliveryTime = currentTime;
2401
2402 // Publish the event.
2403 status_t status;
2404 EventEntry* eventEntry = dispatchEntry->eventEntry;
2405 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002406 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002407 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002408
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002409 // Publish the key event.
2410 status = connection->inputPublisher
2411 .publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId,
2412 keyEntry->source, keyEntry->displayId,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06002413 INVALID_HMAC, dispatchEntry->resolvedAction,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002414 dispatchEntry->resolvedFlags, keyEntry->keyCode,
2415 keyEntry->scanCode, keyEntry->metaState,
2416 keyEntry->repeatCount, keyEntry->downTime,
2417 keyEntry->eventTime);
2418 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002419 }
2420
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002421 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002422 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002423
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002424 PointerCoords scaledCoords[MAX_POINTERS];
2425 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2426
chaviw82357092020-01-28 13:13:06 -08002427 // Set the X and Y offset and X and Y scale depending on the input source.
2428 float xOffset = 0.0f, yOffset = 0.0f;
2429 float xScale = 1.0f, yScale = 1.0f;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002430 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
2431 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2432 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002433 xScale = dispatchEntry->windowXScale;
2434 yScale = dispatchEntry->windowYScale;
2435 xOffset = dispatchEntry->xOffset * xScale;
2436 yOffset = dispatchEntry->yOffset * yScale;
2437 if (globalScaleFactor != 1.0f) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002438 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2439 scaledCoords[i] = motionEntry->pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002440 // Don't apply window scale here since we don't want scale to affect raw
2441 // coordinates. The scale will be sent back to the client and applied
2442 // later when requesting relative coordinates.
2443 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2444 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002445 }
2446 usingCoords = scaledCoords;
2447 }
2448 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002449 // We don't want the dispatch target to know.
2450 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
2451 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2452 scaledCoords[i].clear();
2453 }
2454 usingCoords = scaledCoords;
2455 }
2456 }
2457
2458 // Publish the motion event.
2459 status = connection->inputPublisher
2460 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2461 motionEntry->source, motionEntry->displayId,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06002462 INVALID_HMAC, dispatchEntry->resolvedAction,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002463 motionEntry->actionButton,
2464 dispatchEntry->resolvedFlags,
2465 motionEntry->edgeFlags, motionEntry->metaState,
2466 motionEntry->buttonState,
chaviw82357092020-01-28 13:13:06 -08002467 motionEntry->classification, xScale, yScale,
2468 xOffset, yOffset, motionEntry->xPrecision,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002469 motionEntry->yPrecision,
2470 motionEntry->xCursorPosition,
2471 motionEntry->yCursorPosition,
2472 motionEntry->downTime, motionEntry->eventTime,
2473 motionEntry->pointerCount,
2474 motionEntry->pointerProperties, usingCoords);
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05002475 reportTouchEventForStatistics(*motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002476 break;
2477 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002478 case EventEntry::Type::FOCUS: {
2479 FocusEntry* focusEntry = static_cast<FocusEntry*>(eventEntry);
2480 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
2481 focusEntry->hasFocus,
2482 mInTouchMode);
2483 break;
2484 }
2485
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002486 case EventEntry::Type::CONFIGURATION_CHANGED:
2487 case EventEntry::Type::DEVICE_RESET: {
2488 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
2489 EventEntry::typeToString(eventEntry->type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002490 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002491 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002492 }
2493
2494 // Check the result.
2495 if (status) {
2496 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002497 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002498 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002499 "This is unexpected because the wait queue is empty, so the pipe "
2500 "should be empty and we shouldn't have any problems writing an "
2501 "event to it, status=%d",
2502 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002503 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2504 } else {
2505 // Pipe is full and we are waiting for the app to finish process some events
2506 // before sending more events to it.
2507#if DEBUG_DISPATCH_CYCLE
2508 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002509 "waiting for the application to catch up",
2510 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002511#endif
2512 connection->inputPublisherBlocked = true;
2513 }
2514 } else {
2515 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002516 "status=%d",
2517 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002518 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2519 }
2520 return;
2521 }
2522
2523 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002524 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2525 connection->outboundQueue.end(),
2526 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002527 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002528 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002529 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002530 }
2531}
2532
2533void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002534 const sp<Connection>& connection, uint32_t seq,
2535 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002536#if DEBUG_DISPATCH_CYCLE
2537 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002538 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002539#endif
2540
2541 connection->inputPublisherBlocked = false;
2542
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002543 if (connection->status == Connection::STATUS_BROKEN ||
2544 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002545 return;
2546 }
2547
2548 // Notify other system components and prepare to start the next dispatch cycle.
2549 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2550}
2551
2552void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002553 const sp<Connection>& connection,
2554 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002555#if DEBUG_DISPATCH_CYCLE
2556 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002557 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002558#endif
2559
2560 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002561 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002562 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002563 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002564 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002565
2566 // The connection appears to be unrecoverably broken.
2567 // Ignore already broken or zombie connections.
2568 if (connection->status == Connection::STATUS_NORMAL) {
2569 connection->status = Connection::STATUS_BROKEN;
2570
2571 if (notify) {
2572 // Notify other system components.
2573 onDispatchCycleBrokenLocked(currentTime, connection);
2574 }
2575 }
2576}
2577
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002578void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2579 while (!queue.empty()) {
2580 DispatchEntry* dispatchEntry = queue.front();
2581 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002582 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002583 }
2584}
2585
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002586void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002587 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002588 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002589 }
2590 delete dispatchEntry;
2591}
2592
2593int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2594 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2595
2596 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002597 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002598
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002599 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002600 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002601 "fd=%d, events=0x%x",
2602 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002603 return 0; // remove the callback
2604 }
2605
2606 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002607 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002608 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2609 if (!(events & ALOOPER_EVENT_INPUT)) {
2610 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002611 "events=0x%x",
2612 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002613 return 1;
2614 }
2615
2616 nsecs_t currentTime = now();
2617 bool gotOne = false;
2618 status_t status;
2619 for (;;) {
2620 uint32_t seq;
2621 bool handled;
2622 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2623 if (status) {
2624 break;
2625 }
2626 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2627 gotOne = true;
2628 }
2629 if (gotOne) {
2630 d->runCommandsLockedInterruptible();
2631 if (status == WOULD_BLOCK) {
2632 return 1;
2633 }
2634 }
2635
2636 notify = status != DEAD_OBJECT || !connection->monitor;
2637 if (notify) {
2638 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002639 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002640 }
2641 } else {
2642 // Monitor channels are never explicitly unregistered.
2643 // We do it automatically when the remote endpoint is closed so don't warn
2644 // about them.
2645 notify = !connection->monitor;
2646 if (notify) {
2647 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002648 "events=0x%x",
2649 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002650 }
2651 }
2652
2653 // Unregister the channel.
2654 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2655 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002656 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08002657}
2658
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002659void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002660 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002661 for (const auto& pair : mConnectionsByFd) {
2662 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002663 }
2664}
2665
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002666void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002667 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002668 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2669 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2670}
2671
2672void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2673 const CancelationOptions& options,
2674 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2675 for (const auto& it : monitorsByDisplay) {
2676 const std::vector<Monitor>& monitors = it.second;
2677 for (const Monitor& monitor : monitors) {
2678 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002679 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002680 }
2681}
2682
Michael Wrightd02c5b62014-02-10 15:10:22 -08002683void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2684 const sp<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002685 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002686 if (connection == nullptr) {
2687 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002688 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002689
2690 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002691}
2692
2693void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2694 const sp<Connection>& connection, const CancelationOptions& options) {
2695 if (connection->status == Connection::STATUS_BROKEN) {
2696 return;
2697 }
2698
2699 nsecs_t currentTime = now();
2700
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07002701 std::vector<EventEntry*> cancelationEvents =
2702 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002703
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002704 if (cancelationEvents.empty()) {
2705 return;
2706 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002707#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002708 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
2709 "with reality: %s, mode=%d.",
2710 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
2711 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002712#endif
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002713 for (size_t i = 0; i < cancelationEvents.size(); i++) {
2714 EventEntry* cancelationEventEntry = cancelationEvents[i];
2715 switch (cancelationEventEntry->type) {
2716 case EventEntry::Type::KEY: {
2717 logOutboundKeyDetails("cancel - ",
2718 static_cast<const KeyEntry&>(*cancelationEventEntry));
2719 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002720 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002721 case EventEntry::Type::MOTION: {
2722 logOutboundMotionDetails("cancel - ",
2723 static_cast<const MotionEntry&>(*cancelationEventEntry));
2724 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002725 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002726 case EventEntry::Type::FOCUS: {
2727 LOG_ALWAYS_FATAL("Canceling focus events is not supported");
2728 break;
2729 }
2730 case EventEntry::Type::CONFIGURATION_CHANGED:
2731 case EventEntry::Type::DEVICE_RESET: {
2732 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2733 EventEntry::typeToString(cancelationEventEntry->type));
2734 break;
2735 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002736 }
2737
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002738 InputTarget target;
2739 sp<InputWindowHandle> windowHandle =
2740 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
2741 if (windowHandle != nullptr) {
2742 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2743 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2744 windowInfo->windowXScale, windowInfo->windowYScale);
2745 target.globalScaleFactor = windowInfo->globalScaleFactor;
2746 }
2747 target.inputChannel = connection->inputChannel;
2748 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2749
2750 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
2751 target, InputTarget::FLAG_DISPATCH_AS_IS);
2752
2753 cancelationEventEntry->release();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002754 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002755
2756 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002757}
2758
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002759MotionEntry* InputDispatcher::splitMotionEvent(const MotionEntry& originalMotionEntry,
Garfield Tane84e6f92019-08-29 17:28:41 -07002760 BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002761 ALOG_ASSERT(pointerIds.value != 0);
2762
2763 uint32_t splitPointerIndexMap[MAX_POINTERS];
2764 PointerProperties splitPointerProperties[MAX_POINTERS];
2765 PointerCoords splitPointerCoords[MAX_POINTERS];
2766
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002767 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002768 uint32_t splitPointerCount = 0;
2769
2770 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002771 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002772 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002773 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002774 uint32_t pointerId = uint32_t(pointerProperties.id);
2775 if (pointerIds.hasBit(pointerId)) {
2776 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2777 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2778 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002779 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002780 splitPointerCount += 1;
2781 }
2782 }
2783
2784 if (splitPointerCount != pointerIds.count()) {
2785 // This is bad. We are missing some of the pointers that we expected to deliver.
2786 // Most likely this indicates that we received an ACTION_MOVE events that has
2787 // different pointer ids than we expected based on the previous ACTION_DOWN
2788 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2789 // in this way.
2790 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002791 "we expected there to be %d pointers. This probably means we received "
2792 "a broken sequence of pointer ids from the input device.",
2793 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002794 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002795 }
2796
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002797 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002798 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002799 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
2800 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002801 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2802 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002803 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002804 uint32_t pointerId = uint32_t(pointerProperties.id);
2805 if (pointerIds.hasBit(pointerId)) {
2806 if (pointerIds.count() == 1) {
2807 // The first/last pointer went down/up.
2808 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002809 ? AMOTION_EVENT_ACTION_DOWN
2810 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002811 } else {
2812 // A secondary pointer went down/up.
2813 uint32_t splitPointerIndex = 0;
2814 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2815 splitPointerIndex += 1;
2816 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002817 action = maskedAction |
2818 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002819 }
2820 } else {
2821 // An unrelated pointer changed.
2822 action = AMOTION_EVENT_ACTION_MOVE;
2823 }
2824 }
2825
Garfield Tan00f511d2019-06-12 16:55:40 -07002826 MotionEntry* splitMotionEntry =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002827 new MotionEntry(originalMotionEntry.sequenceNum, originalMotionEntry.eventTime,
2828 originalMotionEntry.deviceId, originalMotionEntry.source,
2829 originalMotionEntry.displayId, originalMotionEntry.policyFlags, action,
2830 originalMotionEntry.actionButton, originalMotionEntry.flags,
2831 originalMotionEntry.metaState, originalMotionEntry.buttonState,
2832 originalMotionEntry.classification, originalMotionEntry.edgeFlags,
2833 originalMotionEntry.xPrecision, originalMotionEntry.yPrecision,
2834 originalMotionEntry.xCursorPosition,
2835 originalMotionEntry.yCursorPosition, originalMotionEntry.downTime,
Garfield Tan00f511d2019-06-12 16:55:40 -07002836 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002837
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002838 if (originalMotionEntry.injectionState) {
2839 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002840 splitMotionEntry->injectionState->refCount += 1;
2841 }
2842
2843 return splitMotionEntry;
2844}
2845
2846void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2847#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002848 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002849#endif
2850
2851 bool needWake;
2852 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002853 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002854
Prabir Pradhan42611e02018-11-27 14:04:02 -08002855 ConfigurationChangedEntry* newEntry =
2856 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002857 needWake = enqueueInboundEventLocked(newEntry);
2858 } // release lock
2859
2860 if (needWake) {
2861 mLooper->wake();
2862 }
2863}
2864
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002865/**
2866 * If one of the meta shortcuts is detected, process them here:
2867 * Meta + Backspace -> generate BACK
2868 * Meta + Enter -> generate HOME
2869 * This will potentially overwrite keyCode and metaState.
2870 */
2871void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002872 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002873 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2874 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2875 if (keyCode == AKEYCODE_DEL) {
2876 newKeyCode = AKEYCODE_BACK;
2877 } else if (keyCode == AKEYCODE_ENTER) {
2878 newKeyCode = AKEYCODE_HOME;
2879 }
2880 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002881 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002882 struct KeyReplacement replacement = {keyCode, deviceId};
2883 mReplacedKeys.add(replacement, newKeyCode);
2884 keyCode = newKeyCode;
2885 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2886 }
2887 } else if (action == AKEY_EVENT_ACTION_UP) {
2888 // In order to maintain a consistent stream of up and down events, check to see if the key
2889 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2890 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002891 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002892 struct KeyReplacement replacement = {keyCode, deviceId};
2893 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2894 if (index >= 0) {
2895 keyCode = mReplacedKeys.valueAt(index);
2896 mReplacedKeys.removeItemsAt(index);
2897 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2898 }
2899 }
2900}
2901
Michael Wrightd02c5b62014-02-10 15:10:22 -08002902void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2903#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002904 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
2905 "policyFlags=0x%x, action=0x%x, "
2906 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
2907 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2908 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
2909 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002910#endif
2911 if (!validateKeyEvent(args->action)) {
2912 return;
2913 }
2914
2915 uint32_t policyFlags = args->policyFlags;
2916 int32_t flags = args->flags;
2917 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002918 // InputDispatcher tracks and generates key repeats on behalf of
2919 // whatever notifies it, so repeatCount should always be set to 0
2920 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002921 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2922 policyFlags |= POLICY_FLAG_VIRTUAL;
2923 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2924 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002925 if (policyFlags & POLICY_FLAG_FUNCTION) {
2926 metaState |= AMETA_FUNCTION_ON;
2927 }
2928
2929 policyFlags |= POLICY_FLAG_TRUSTED;
2930
Michael Wright78f24442014-08-06 15:55:28 -07002931 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002932 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002933
Michael Wrightd02c5b62014-02-10 15:10:22 -08002934 KeyEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06002935 event.initialize(args->deviceId, args->source, args->displayId, INVALID_HMAC, args->action,
2936 flags, keyCode, args->scanCode, metaState, repeatCount, args->downTime,
2937 args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002938
Michael Wright2b3c3302018-03-02 17:19:13 +00002939 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002940 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002941 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2942 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002943 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00002944 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002945
Michael Wrightd02c5b62014-02-10 15:10:22 -08002946 bool needWake;
2947 { // acquire lock
2948 mLock.lock();
2949
2950 if (shouldSendKeyToInputFilterLocked(args)) {
2951 mLock.unlock();
2952
2953 policyFlags |= POLICY_FLAG_FILTERED;
2954 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2955 return; // event was consumed by the filter
2956 }
2957
2958 mLock.lock();
2959 }
2960
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002961 KeyEntry* newEntry =
2962 new KeyEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2963 args->displayId, policyFlags, args->action, flags, keyCode,
2964 args->scanCode, metaState, repeatCount, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002965
2966 needWake = enqueueInboundEventLocked(newEntry);
2967 mLock.unlock();
2968 } // release lock
2969
2970 if (needWake) {
2971 mLooper->wake();
2972 }
2973}
2974
2975bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2976 return mInputFilterEnabled;
2977}
2978
2979void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2980#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002981 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07002982 ", policyFlags=0x%x, "
2983 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
2984 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07002985 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07002986 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2987 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
Jaewan Kim372fbe42019-10-02 10:58:46 +09002988 args->edgeFlags, args->xPrecision, args->yPrecision, args->xCursorPosition,
Garfield Tan00f511d2019-06-12 16:55:40 -07002989 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002990 for (uint32_t i = 0; i < args->pointerCount; i++) {
2991 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002992 "x=%f, y=%f, pressure=%f, size=%f, "
2993 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2994 "orientation=%f",
2995 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
2996 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2997 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2998 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2999 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3000 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3001 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3002 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3003 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3004 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003005 }
3006#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003007 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3008 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003009 return;
3010 }
3011
3012 uint32_t policyFlags = args->policyFlags;
3013 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003014
3015 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003016 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003017 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3018 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003019 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003020 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003021
3022 bool needWake;
3023 { // acquire lock
3024 mLock.lock();
3025
3026 if (shouldSendMotionToInputFilterLocked(args)) {
3027 mLock.unlock();
3028
3029 MotionEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06003030 event.initialize(args->deviceId, args->source, args->displayId, INVALID_HMAC,
3031 args->action, args->actionButton, args->flags, args->edgeFlags,
3032 args->metaState, args->buttonState, args->classification, 1 /*xScale*/,
3033 1 /*yScale*/, 0 /* xOffset */, 0 /* yOffset */, args->xPrecision,
Garfield Tan00f511d2019-06-12 16:55:40 -07003034 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3035 args->downTime, args->eventTime, args->pointerCount,
3036 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003037
3038 policyFlags |= POLICY_FLAG_FILTERED;
3039 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3040 return; // event was consumed by the filter
3041 }
3042
3043 mLock.lock();
3044 }
3045
3046 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07003047 MotionEntry* newEntry =
3048 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
3049 args->displayId, policyFlags, args->action, args->actionButton,
3050 args->flags, args->metaState, args->buttonState,
3051 args->classification, args->edgeFlags, args->xPrecision,
3052 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3053 args->downTime, args->pointerCount, args->pointerProperties,
3054 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003055
3056 needWake = enqueueInboundEventLocked(newEntry);
3057 mLock.unlock();
3058 } // release lock
3059
3060 if (needWake) {
3061 mLooper->wake();
3062 }
3063}
3064
3065bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003066 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003067}
3068
3069void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3070#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003071 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003072 "switchMask=0x%08x",
3073 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003074#endif
3075
3076 uint32_t policyFlags = args->policyFlags;
3077 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003078 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003079}
3080
3081void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3082#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003083 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3084 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003085#endif
3086
3087 bool needWake;
3088 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003089 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003090
Prabir Pradhan42611e02018-11-27 14:04:02 -08003091 DeviceResetEntry* newEntry =
3092 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003093 needWake = enqueueInboundEventLocked(newEntry);
3094 } // release lock
3095
3096 if (needWake) {
3097 mLooper->wake();
3098 }
3099}
3100
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003101int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid,
3102 int32_t injectorUid, int32_t syncMode,
3103 int32_t timeoutMillis, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003104#if DEBUG_INBOUND_EVENT_DETAILS
3105 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003106 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
3107 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003108#endif
3109
3110 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
3111
3112 policyFlags |= POLICY_FLAG_INJECTED;
3113 if (hasInjectionPermission(injectorPid, injectorUid)) {
3114 policyFlags |= POLICY_FLAG_TRUSTED;
3115 }
3116
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003117 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003118 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003119 case AINPUT_EVENT_TYPE_KEY: {
3120 KeyEvent keyEvent;
3121 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
3122 int32_t action = keyEvent.getAction();
3123 if (!validateKeyEvent(action)) {
3124 return INPUT_EVENT_INJECTION_FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003125 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003126
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003127 int32_t flags = keyEvent.getFlags();
3128 int32_t keyCode = keyEvent.getKeyCode();
3129 int32_t metaState = keyEvent.getMetaState();
3130 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
3131 /*byref*/ keyCode, /*byref*/ metaState);
3132 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(),
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06003133 keyEvent.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003134 keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
3135 keyEvent.getDownTime(), keyEvent.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003136
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003137 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3138 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003139 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003140
3141 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3142 android::base::Timer t;
3143 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3144 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3145 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3146 std::to_string(t.duration().count()).c_str());
3147 }
3148 }
3149
3150 mLock.lock();
3151 KeyEntry* injectedEntry =
3152 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
3153 keyEvent.getDeviceId(), keyEvent.getSource(),
3154 keyEvent.getDisplayId(), policyFlags, action, flags,
3155 keyEvent.getKeyCode(), keyEvent.getScanCode(),
3156 keyEvent.getMetaState(), keyEvent.getRepeatCount(),
3157 keyEvent.getDownTime());
3158 injectedEntries.push(injectedEntry);
3159 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003160 }
3161
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003162 case AINPUT_EVENT_TYPE_MOTION: {
3163 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3164 int32_t action = motionEvent->getAction();
3165 size_t pointerCount = motionEvent->getPointerCount();
3166 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3167 int32_t actionButton = motionEvent->getActionButton();
3168 int32_t displayId = motionEvent->getDisplayId();
3169 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
3170 return INPUT_EVENT_INJECTION_FAILED;
3171 }
3172
3173 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3174 nsecs_t eventTime = motionEvent->getEventTime();
3175 android::base::Timer t;
3176 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3177 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3178 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3179 std::to_string(t.duration().count()).c_str());
3180 }
3181 }
3182
3183 mLock.lock();
3184 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3185 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
3186 MotionEntry* injectedEntry =
Garfield Tan00f511d2019-06-12 16:55:40 -07003187 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3188 motionEvent->getDeviceId(), motionEvent->getSource(),
3189 motionEvent->getDisplayId(), policyFlags, action, actionButton,
3190 motionEvent->getFlags(), motionEvent->getMetaState(),
3191 motionEvent->getButtonState(), motionEvent->getClassification(),
3192 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3193 motionEvent->getYPrecision(),
3194 motionEvent->getRawXCursorPosition(),
3195 motionEvent->getRawYCursorPosition(),
3196 motionEvent->getDownTime(), uint32_t(pointerCount),
3197 pointerProperties, samplePointerCoords,
3198 motionEvent->getXOffset(), motionEvent->getYOffset());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003199 injectedEntries.push(injectedEntry);
3200 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3201 sampleEventTimes += 1;
3202 samplePointerCoords += pointerCount;
3203 MotionEntry* nextInjectedEntry =
3204 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3205 motionEvent->getDeviceId(), motionEvent->getSource(),
3206 motionEvent->getDisplayId(), policyFlags, action,
3207 actionButton, motionEvent->getFlags(),
3208 motionEvent->getMetaState(), motionEvent->getButtonState(),
3209 motionEvent->getClassification(),
3210 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3211 motionEvent->getYPrecision(),
3212 motionEvent->getRawXCursorPosition(),
3213 motionEvent->getRawYCursorPosition(),
3214 motionEvent->getDownTime(), uint32_t(pointerCount),
3215 pointerProperties, samplePointerCoords,
3216 motionEvent->getXOffset(), motionEvent->getYOffset());
3217 injectedEntries.push(nextInjectedEntry);
3218 }
3219 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003220 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003221
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003222 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003223 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003224 return INPUT_EVENT_INJECTION_FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003225 }
3226
3227 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3228 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3229 injectionState->injectionIsAsync = true;
3230 }
3231
3232 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003233 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003234
3235 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003236 while (!injectedEntries.empty()) {
3237 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3238 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003239 }
3240
3241 mLock.unlock();
3242
3243 if (needWake) {
3244 mLooper->wake();
3245 }
3246
3247 int32_t injectionResult;
3248 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003249 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003250
3251 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3252 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3253 } else {
3254 for (;;) {
3255 injectionResult = injectionState->injectionResult;
3256 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3257 break;
3258 }
3259
3260 nsecs_t remainingTimeout = endTime - now();
3261 if (remainingTimeout <= 0) {
3262#if DEBUG_INJECTION
3263 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003264 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003265#endif
3266 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3267 break;
3268 }
3269
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003270 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003271 }
3272
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003273 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED &&
3274 syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003275 while (injectionState->pendingForegroundDispatches != 0) {
3276#if DEBUG_INJECTION
3277 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003278 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003279#endif
3280 nsecs_t remainingTimeout = endTime - now();
3281 if (remainingTimeout <= 0) {
3282#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003283 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3284 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003285#endif
3286 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3287 break;
3288 }
3289
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003290 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003291 }
3292 }
3293 }
3294
3295 injectionState->release();
3296 } // release lock
3297
3298#if DEBUG_INJECTION
3299 ALOGD("injectInputEvent - Finished with result %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003300 "injectorPid=%d, injectorUid=%d",
3301 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003302#endif
3303
3304 return injectionResult;
3305}
3306
3307bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003308 return injectorUid == 0 ||
3309 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003310}
3311
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003312void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003313 InjectionState* injectionState = entry->injectionState;
3314 if (injectionState) {
3315#if DEBUG_INJECTION
3316 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003317 "injectorPid=%d, injectorUid=%d",
3318 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003319#endif
3320
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003321 if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003322 // Log the outcome since the injector did not wait for the injection result.
3323 switch (injectionResult) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003324 case INPUT_EVENT_INJECTION_SUCCEEDED:
3325 ALOGV("Asynchronous input event injection succeeded.");
3326 break;
3327 case INPUT_EVENT_INJECTION_FAILED:
3328 ALOGW("Asynchronous input event injection failed.");
3329 break;
3330 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3331 ALOGW("Asynchronous input event injection permission denied.");
3332 break;
3333 case INPUT_EVENT_INJECTION_TIMED_OUT:
3334 ALOGW("Asynchronous input event injection timed out.");
3335 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003336 }
3337 }
3338
3339 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003340 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003341 }
3342}
3343
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003344void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003345 InjectionState* injectionState = entry->injectionState;
3346 if (injectionState) {
3347 injectionState->pendingForegroundDispatches += 1;
3348 }
3349}
3350
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003351void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003352 InjectionState* injectionState = entry->injectionState;
3353 if (injectionState) {
3354 injectionState->pendingForegroundDispatches -= 1;
3355
3356 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003357 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003358 }
3359 }
3360}
3361
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003362std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3363 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003364 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003365}
3366
Michael Wrightd02c5b62014-02-10 15:10:22 -08003367sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003368 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003369 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003370 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3371 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003372 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003373 return windowHandle;
3374 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003375 }
3376 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003377 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003378}
3379
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003380bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003381 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003382 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3383 for (const sp<InputWindowHandle>& handle : windowHandles) {
3384 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003385 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003386 ALOGE("Found window %s in display %" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003387 ", but it should belong to display %" PRId32,
3388 windowHandle->getName().c_str(), it.first,
3389 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003390 }
3391 return true;
3392 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003393 }
3394 }
3395 return false;
3396}
3397
Robert Carr5c8a0262018-10-03 16:30:44 -07003398sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3399 size_t count = mInputChannelsByToken.count(token);
3400 if (count == 0) {
3401 return nullptr;
3402 }
3403 return mInputChannelsByToken.at(token);
3404}
3405
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003406void InputDispatcher::updateWindowHandlesForDisplayLocked(
3407 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3408 if (inputWindowHandles.empty()) {
3409 // Remove all handles on a display if there are no windows left.
3410 mWindowHandlesByDisplay.erase(displayId);
3411 return;
3412 }
3413
3414 // Since we compare the pointer of input window handles across window updates, we need
3415 // to make sure the handle object for the same window stays unchanged across updates.
3416 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003417 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003418 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003419 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003420 }
3421
3422 std::vector<sp<InputWindowHandle>> newHandles;
3423 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3424 if (!handle->updateInfo()) {
3425 // handle no longer valid
3426 continue;
3427 }
3428
3429 const InputWindowInfo* info = handle->getInfo();
3430 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3431 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3432 const bool noInputChannel =
3433 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3434 const bool canReceiveInput =
3435 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3436 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3437 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003438 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003439 handle->getName().c_str());
3440 }
3441 continue;
3442 }
3443
3444 if (info->displayId != displayId) {
3445 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3446 handle->getName().c_str(), displayId, info->displayId);
3447 continue;
3448 }
3449
chaviwaf87b3e2019-10-01 16:59:28 -07003450 if (oldHandlesById.find(handle->getId()) != oldHandlesById.end()) {
3451 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003452 oldHandle->updateFrom(handle);
3453 newHandles.push_back(oldHandle);
3454 } else {
3455 newHandles.push_back(handle);
3456 }
3457 }
3458
3459 // Insert or replace
3460 mWindowHandlesByDisplay[displayId] = newHandles;
3461}
3462
Arthur Hungb92218b2018-08-14 12:00:21 +08003463/**
3464 * Called from InputManagerService, update window handle list by displayId that can receive input.
3465 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3466 * If set an empty list, remove all handles from the specific display.
3467 * For focused handle, check if need to change and send a cancel event to previous one.
3468 * For removed handle, check if need to send a cancel event if already in touch.
3469 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003470void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003471 int32_t displayId,
3472 const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003473 if (DEBUG_FOCUS) {
3474 std::string windowList;
3475 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
3476 windowList += iwh->getName() + " ";
3477 }
3478 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
3479 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003480 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003481 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003482
Arthur Hungb92218b2018-08-14 12:00:21 +08003483 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003484 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3485 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003486
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003487 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3488
Tiger Huang721e26f2018-07-24 22:26:19 +08003489 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003490 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003491 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3492 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3493 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3494 windowHandle->getInfo()->visible) {
3495 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003496 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003497 if (windowHandle == mLastHoverWindowHandle) {
3498 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003499 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003500 }
3501
3502 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003503 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003504 }
3505
Tiger Huang721e26f2018-07-24 22:26:19 +08003506 sp<InputWindowHandle> oldFocusedWindowHandle =
3507 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3508
chaviwaf87b3e2019-10-01 16:59:28 -07003509 if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003510 if (oldFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003511 if (DEBUG_FOCUS) {
3512 ALOGD("Focus left window: %s in display %" PRId32,
3513 oldFocusedWindowHandle->getName().c_str(), displayId);
3514 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003515 sp<InputChannel> focusedInputChannel =
3516 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003517 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003518 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003519 "focus left window");
3520 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003521 enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003522 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003523 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003524 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003525 if (newFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003526 if (DEBUG_FOCUS) {
3527 ALOGD("Focus entered window: %s in display %" PRId32,
3528 newFocusedWindowHandle->getName().c_str(), displayId);
3529 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003530 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003531 enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003532 }
Robert Carrf759f162018-11-13 12:57:11 -08003533
3534 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003535 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003536 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003537 }
3538
Arthur Hungb92218b2018-08-14 12:00:21 +08003539 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3540 if (stateIndex >= 0) {
3541 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003542 for (size_t i = 0; i < state.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003543 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003544 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003545 if (DEBUG_FOCUS) {
3546 ALOGD("Touched window was removed: %s in display %" PRId32,
3547 touchedWindow.windowHandle->getName().c_str(), displayId);
3548 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003549 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003550 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003551 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003552 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003553 "touched window was removed");
3554 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
3555 options);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003556 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003557 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003558 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003559 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003560 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003561 }
3562 }
3563
3564 // Release information for windows that are no longer present.
3565 // This ensures that unused input channels are released promptly.
3566 // Otherwise, they might stick around until the window handle is destroyed
3567 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003568 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003569 if (!hasWindowHandleLocked(oldWindowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003570 if (DEBUG_FOCUS) {
3571 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
3572 }
Arthur Hung3b413f22018-10-26 18:05:34 +08003573 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003574 }
3575 }
3576 } // release lock
3577
3578 // Wake up poll loop since it may need to make new input dispatching choices.
3579 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003580
3581 if (setInputWindowsListener) {
3582 setInputWindowsListener->onSetInputWindowsFinished();
3583 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003584}
3585
3586void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003587 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003588 if (DEBUG_FOCUS) {
3589 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
3590 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
3591 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003592 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003593 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003594
Tiger Huang721e26f2018-07-24 22:26:19 +08003595 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3596 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003597 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003598 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3599 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003600 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003601 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003602 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003603 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003604 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003605 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003606 oldFocusedApplicationHandle.clear();
3607 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003608 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003609 } // release lock
3610
3611 // Wake up poll loop since it may need to make new input dispatching choices.
3612 mLooper->wake();
3613}
3614
Tiger Huang721e26f2018-07-24 22:26:19 +08003615/**
3616 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3617 * the display not specified.
3618 *
3619 * We track any unreleased events for each window. If a window loses the ability to receive the
3620 * released event, we will send a cancel event to it. So when the focused display is changed, we
3621 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3622 * display. The display-specified events won't be affected.
3623 */
3624void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003625 if (DEBUG_FOCUS) {
3626 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3627 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003628 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003629 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003630
3631 if (mFocusedDisplayId != displayId) {
3632 sp<InputWindowHandle> oldFocusedWindowHandle =
3633 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3634 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003635 sp<InputChannel> inputChannel =
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003636 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003637 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003638 CancelationOptions
3639 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3640 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003641 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003642 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3643 }
3644 }
3645 mFocusedDisplayId = displayId;
3646
3647 // Sanity check
3648 sp<InputWindowHandle> newFocusedWindowHandle =
3649 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003650 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003651
Tiger Huang721e26f2018-07-24 22:26:19 +08003652 if (newFocusedWindowHandle == nullptr) {
3653 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3654 if (!mFocusedWindowHandlesByDisplay.empty()) {
3655 ALOGE("But another display has a focused window:");
3656 for (auto& it : mFocusedWindowHandlesByDisplay) {
3657 const int32_t displayId = it.first;
3658 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003659 ALOGE("Display #%" PRId32 " has focused window: '%s'\n", displayId,
3660 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003661 }
3662 }
3663 }
3664 }
3665
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003666 if (DEBUG_FOCUS) {
3667 logDispatchStateLocked();
3668 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003669 } // release lock
3670
3671 // Wake up poll loop since it may need to make new input dispatching choices.
3672 mLooper->wake();
3673}
3674
Michael Wrightd02c5b62014-02-10 15:10:22 -08003675void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003676 if (DEBUG_FOCUS) {
3677 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3678 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003679
3680 bool changed;
3681 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003682 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003683
3684 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3685 if (mDispatchFrozen && !frozen) {
3686 resetANRTimeoutsLocked();
3687 }
3688
3689 if (mDispatchEnabled && !enabled) {
3690 resetAndDropEverythingLocked("dispatcher is being disabled");
3691 }
3692
3693 mDispatchEnabled = enabled;
3694 mDispatchFrozen = frozen;
3695 changed = true;
3696 } else {
3697 changed = false;
3698 }
3699
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003700 if (DEBUG_FOCUS) {
3701 logDispatchStateLocked();
3702 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003703 } // release lock
3704
3705 if (changed) {
3706 // Wake up poll loop since it may need to make new input dispatching choices.
3707 mLooper->wake();
3708 }
3709}
3710
3711void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003712 if (DEBUG_FOCUS) {
3713 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3714 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003715
3716 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003717 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003718
3719 if (mInputFilterEnabled == enabled) {
3720 return;
3721 }
3722
3723 mInputFilterEnabled = enabled;
3724 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3725 } // release lock
3726
3727 // Wake up poll loop since there might be work to do to drop everything.
3728 mLooper->wake();
3729}
3730
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08003731void InputDispatcher::setInTouchMode(bool inTouchMode) {
3732 std::scoped_lock lock(mLock);
3733 mInTouchMode = inTouchMode;
3734}
3735
chaviwfbe5d9c2018-12-26 12:23:37 -08003736bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3737 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003738 if (DEBUG_FOCUS) {
3739 ALOGD("Trivial transfer to same window.");
3740 }
chaviwfbe5d9c2018-12-26 12:23:37 -08003741 return true;
3742 }
3743
Michael Wrightd02c5b62014-02-10 15:10:22 -08003744 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003745 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003746
chaviwfbe5d9c2018-12-26 12:23:37 -08003747 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3748 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003749 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003750 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003751 return false;
3752 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003753 if (DEBUG_FOCUS) {
3754 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3755 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3756 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003757 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003758 if (DEBUG_FOCUS) {
3759 ALOGD("Cannot transfer focus because windows are on different displays.");
3760 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003761 return false;
3762 }
3763
3764 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003765 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3766 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3767 for (size_t i = 0; i < state.windows.size(); i++) {
3768 const TouchedWindow& touchedWindow = state.windows[i];
3769 if (touchedWindow.windowHandle == fromWindowHandle) {
3770 int32_t oldTargetFlags = touchedWindow.targetFlags;
3771 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003772
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003773 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003774
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003775 int32_t newTargetFlags = oldTargetFlags &
3776 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
3777 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003778 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003779
Jeff Brownf086ddb2014-02-11 14:28:48 -08003780 found = true;
3781 goto Found;
3782 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003783 }
3784 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003785 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003786
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003787 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003788 if (DEBUG_FOCUS) {
3789 ALOGD("Focus transfer failed because from window did not have focus.");
3790 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003791 return false;
3792 }
3793
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07003794 sp<Connection> fromConnection = getConnectionLocked(fromToken);
3795 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003796 if (fromConnection != nullptr && toConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003797 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003798 CancelationOptions
3799 options(CancelationOptions::CANCEL_POINTER_EVENTS,
3800 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003801 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
3802 }
3803
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003804 if (DEBUG_FOCUS) {
3805 logDispatchStateLocked();
3806 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003807 } // release lock
3808
3809 // Wake up poll loop since it may need to make new input dispatching choices.
3810 mLooper->wake();
3811 return true;
3812}
3813
3814void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003815 if (DEBUG_FOCUS) {
3816 ALOGD("Resetting and dropping all events (%s).", reason);
3817 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003818
3819 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3820 synthesizeCancelationEventsForAllConnectionsLocked(options);
3821
3822 resetKeyRepeatLocked();
3823 releasePendingEventLocked();
3824 drainInboundQueueLocked();
3825 resetANRTimeoutsLocked();
3826
Jeff Brownf086ddb2014-02-11 14:28:48 -08003827 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003828 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003829 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003830}
3831
3832void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003833 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003834 dumpDispatchStateLocked(dump);
3835
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003836 std::istringstream stream(dump);
3837 std::string line;
3838
3839 while (std::getline(stream, line, '\n')) {
3840 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003841 }
3842}
3843
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003844void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003845 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3846 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3847 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003848 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003849
Tiger Huang721e26f2018-07-24 22:26:19 +08003850 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3851 dump += StringPrintf(INDENT "FocusedApplications:\n");
3852 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3853 const int32_t displayId = it.first;
3854 const sp<InputApplicationHandle>& applicationHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003855 dump += StringPrintf(INDENT2 "displayId=%" PRId32
3856 ", name='%s', dispatchingTimeout=%0.3fms\n",
3857 displayId, applicationHandle->getName().c_str(),
3858 applicationHandle->getDispatchingTimeout(
3859 DEFAULT_INPUT_DISPATCHING_TIMEOUT) /
3860 1000000.0);
Tiger Huang721e26f2018-07-24 22:26:19 +08003861 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003862 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003863 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003864 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003865
3866 if (!mFocusedWindowHandlesByDisplay.empty()) {
3867 dump += StringPrintf(INDENT "FocusedWindows:\n");
3868 for (auto& it : mFocusedWindowHandlesByDisplay) {
3869 const int32_t displayId = it.first;
3870 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003871 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
3872 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003873 }
3874 } else {
3875 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3876 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003877
Jeff Brownf086ddb2014-02-11 14:28:48 -08003878 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003879 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003880 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3881 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003882 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003883 state.displayId, toString(state.down), toString(state.split),
3884 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003885 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003886 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003887 for (size_t i = 0; i < state.windows.size(); i++) {
3888 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003889 dump += StringPrintf(INDENT4
3890 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3891 i, touchedWindow.windowHandle->getName().c_str(),
3892 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003893 }
3894 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003895 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003896 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003897 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003898 dump += INDENT3 "Portal windows:\n";
3899 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003900 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003901 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
3902 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003903 }
3904 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003905 }
3906 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003907 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003908 }
3909
Arthur Hungb92218b2018-08-14 12:00:21 +08003910 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003911 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003912 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003913 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003914 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003915 dump += INDENT2 "Windows:\n";
3916 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003917 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003918 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003919
Arthur Hungb92218b2018-08-14 12:00:21 +08003920 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003921 "portalToDisplayId=%d, paused=%s, hasFocus=%s, "
chaviwcb923212019-12-30 14:05:11 -08003922 "hasWallpaper=%s, visible=%s, canReceiveKeys=%s, "
3923 "flags=0x%08x, type=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003924 "frame=[%d,%d][%d,%d], globalScale=%f, "
chaviwcb923212019-12-30 14:05:11 -08003925 "windowScale=(%f,%f), touchableRegion=",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003926 i, windowInfo->name.c_str(), windowInfo->displayId,
3927 windowInfo->portalToDisplayId,
3928 toString(windowInfo->paused),
3929 toString(windowInfo->hasFocus),
3930 toString(windowInfo->hasWallpaper),
3931 toString(windowInfo->visible),
3932 toString(windowInfo->canReceiveKeys),
3933 windowInfo->layoutParamsFlags,
chaviwcb923212019-12-30 14:05:11 -08003934 windowInfo->layoutParamsType, windowInfo->frameLeft,
3935 windowInfo->frameTop, windowInfo->frameRight,
3936 windowInfo->frameBottom, windowInfo->globalScaleFactor,
3937 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003938 dumpRegion(dump, windowInfo->touchableRegion);
3939 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3940 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003941 windowInfo->ownerPid, windowInfo->ownerUid,
3942 windowInfo->dispatchingTimeout / 1000000.0);
Arthur Hungb92218b2018-08-14 12:00:21 +08003943 }
3944 } else {
3945 dump += INDENT2 "Windows: <none>\n";
3946 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003947 }
3948 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003949 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003950 }
3951
Michael Wright3dd60e22019-03-27 22:06:44 +00003952 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003953 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003954 const std::vector<Monitor>& monitors = it.second;
3955 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3956 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003957 }
3958 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003959 const std::vector<Monitor>& monitors = it.second;
3960 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
3961 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003962 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003963 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00003964 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003965 }
3966
3967 nsecs_t currentTime = now();
3968
3969 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003970 if (!mRecentQueue.empty()) {
3971 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
3972 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003973 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003974 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003975 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976 }
3977 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003978 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003979 }
3980
3981 // Dump event currently being dispatched.
3982 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003983 dump += INDENT "PendingEvent:\n";
3984 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003985 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003986 dump += StringPrintf(", age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003987 (currentTime - mPendingEvent->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003988 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003989 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003990 }
3991
3992 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003993 if (!mInboundQueue.empty()) {
3994 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
3995 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003996 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003997 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003998 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003999 }
4000 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004001 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004002 }
4003
Michael Wright78f24442014-08-06 15:55:28 -07004004 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004005 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07004006 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
4007 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
4008 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004009 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n", i,
4010 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004011 }
4012 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004013 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004014 }
4015
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004016 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004017 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004018 for (const auto& pair : mConnectionsByFd) {
4019 const sp<Connection>& connection = pair.second;
4020 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
4021 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
4022 pair.first, connection->getInputChannelName().c_str(),
4023 connection->getWindowName().c_str(), connection->getStatusLabel(),
4024 toString(connection->monitor),
4025 toString(connection->inputPublisherBlocked));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004026
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004027 if (!connection->outboundQueue.empty()) {
4028 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4029 connection->outboundQueue.size());
4030 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004031 dump.append(INDENT4);
4032 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004033 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004034 entry->targetFlags, entry->resolvedAction,
4035 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004036 }
4037 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004038 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004039 }
4040
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004041 if (!connection->waitQueue.empty()) {
4042 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4043 connection->waitQueue.size());
4044 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004045 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004046 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004047 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004048 "age=%0.1fms, wait=%0.1fms\n",
4049 entry->targetFlags, entry->resolvedAction,
4050 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
4051 (currentTime - entry->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004052 }
4053 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004054 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004055 }
4056 }
4057 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004058 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004059 }
4060
4061 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004062 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004063 (mAppSwitchDueTime - now()) / 1000000.0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004064 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004065 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004066 }
4067
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004068 dump += INDENT "Configuration:\n";
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004069 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004070 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004071 mConfig.keyRepeatTimeout * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004072}
4073
Michael Wright3dd60e22019-03-27 22:06:44 +00004074void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4075 const size_t numMonitors = monitors.size();
4076 for (size_t i = 0; i < numMonitors; i++) {
4077 const Monitor& monitor = monitors[i];
4078 const sp<InputChannel>& channel = monitor.inputChannel;
4079 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4080 dump += "\n";
4081 }
4082}
4083
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004084status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004085#if DEBUG_REGISTRATION
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004086 ALOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004087#endif
4088
4089 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004090 std::scoped_lock _l(mLock);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004091 sp<Connection> existingConnection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004092 if (existingConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004093 ALOGW("Attempted to register already registered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004094 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004095 return BAD_VALUE;
4096 }
4097
Michael Wright3dd60e22019-03-27 22:06:44 +00004098 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004099
4100 int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004101 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004102 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004103
Michael Wrightd02c5b62014-02-10 15:10:22 -08004104 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4105 } // release lock
4106
4107 // Wake the looper because some connections have changed.
4108 mLooper->wake();
4109 return OK;
4110}
4111
Michael Wright3dd60e22019-03-27 22:06:44 +00004112status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004113 int32_t displayId, bool isGestureMonitor) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004114 { // acquire lock
4115 std::scoped_lock _l(mLock);
4116
4117 if (displayId < 0) {
4118 ALOGW("Attempted to register input monitor without a specified display.");
4119 return BAD_VALUE;
4120 }
4121
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004122 if (inputChannel->getConnectionToken() == nullptr) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004123 ALOGW("Attempted to register input monitor without an identifying token.");
4124 return BAD_VALUE;
4125 }
4126
4127 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
4128
4129 const int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004130 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004131 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004132
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004133 auto& monitorsByDisplay =
4134 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Michael Wright3dd60e22019-03-27 22:06:44 +00004135 monitorsByDisplay[displayId].emplace_back(inputChannel);
4136
4137 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004138 }
4139 // Wake the looper because some connections have changed.
4140 mLooper->wake();
4141 return OK;
4142}
4143
Michael Wrightd02c5b62014-02-10 15:10:22 -08004144status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
4145#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004146 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004147#endif
4148
4149 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004150 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004151
4152 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
4153 if (status) {
4154 return status;
4155 }
4156 } // release lock
4157
4158 // Wake the poll loop because removing the connection may have changed the current
4159 // synchronization state.
4160 mLooper->wake();
4161 return OK;
4162}
4163
4164status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004165 bool notify) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004166 sp<Connection> connection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004167 if (connection == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004168 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004169 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004170 return BAD_VALUE;
4171 }
4172
John Recke0710582019-09-26 13:46:12 -07004173 [[maybe_unused]] const bool removed = removeByValue(mConnectionsByFd, connection);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004174 ALOG_ASSERT(removed);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004175 mInputChannelsByToken.erase(inputChannel->getConnectionToken());
Robert Carr5c8a0262018-10-03 16:30:44 -07004176
Michael Wrightd02c5b62014-02-10 15:10:22 -08004177 if (connection->monitor) {
4178 removeMonitorChannelLocked(inputChannel);
4179 }
4180
4181 mLooper->removeFd(inputChannel->getFd());
4182
4183 nsecs_t currentTime = now();
4184 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4185
4186 connection->status = Connection::STATUS_ZOMBIE;
4187 return OK;
4188}
4189
4190void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004191 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4192 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4193}
4194
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004195void InputDispatcher::removeMonitorChannelLocked(
4196 const sp<InputChannel>& inputChannel,
Michael Wright3dd60e22019-03-27 22:06:44 +00004197 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004198 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004199 std::vector<Monitor>& monitors = it->second;
4200 const size_t numMonitors = monitors.size();
4201 for (size_t i = 0; i < numMonitors; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004202 if (monitors[i].inputChannel == inputChannel) {
4203 monitors.erase(monitors.begin() + i);
4204 break;
4205 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004206 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004207 if (monitors.empty()) {
4208 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004209 } else {
4210 ++it;
4211 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004212 }
4213}
4214
Michael Wright3dd60e22019-03-27 22:06:44 +00004215status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4216 { // acquire lock
4217 std::scoped_lock _l(mLock);
4218 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4219
4220 if (!foundDisplayId) {
4221 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4222 return BAD_VALUE;
4223 }
4224 int32_t displayId = foundDisplayId.value();
4225
4226 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4227 if (stateIndex < 0) {
4228 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4229 return BAD_VALUE;
4230 }
4231
4232 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4233 std::optional<int32_t> foundDeviceId;
4234 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004235 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004236 foundDeviceId = state.deviceId;
4237 }
4238 }
4239 if (!foundDeviceId || !state.down) {
4240 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004241 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004242 return BAD_VALUE;
4243 }
4244 int32_t deviceId = foundDeviceId.value();
4245
4246 // Send cancel events to all the input channels we're stealing from.
4247 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004248 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004249 options.deviceId = deviceId;
4250 options.displayId = displayId;
4251 for (const TouchedWindow& window : state.windows) {
4252 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004253 if (channel != nullptr) {
4254 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4255 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004256 }
4257 // Then clear the current touch state so we stop dispatching to them as well.
4258 state.filterNonMonitors();
4259 }
4260 return OK;
4261}
4262
Michael Wright3dd60e22019-03-27 22:06:44 +00004263std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4264 const sp<IBinder>& token) {
4265 for (const auto& it : mGestureMonitorsByDisplay) {
4266 const std::vector<Monitor>& monitors = it.second;
4267 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004268 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004269 return it.first;
4270 }
4271 }
4272 }
4273 return std::nullopt;
4274}
4275
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004276sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) {
4277 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004278 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004279 }
4280
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004281 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004282 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004283 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004284 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004285 }
4286 }
Robert Carr4e670e52018-08-15 13:26:12 -07004287
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004288 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004289}
4290
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004291void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4292 const sp<Connection>& connection, uint32_t seq,
4293 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004294 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4295 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004296 commandEntry->connection = connection;
4297 commandEntry->eventTime = currentTime;
4298 commandEntry->seq = seq;
4299 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004300 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004301}
4302
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004303void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4304 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004305 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004306 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004307
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004308 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4309 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004310 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004311 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004312}
4313
chaviw0c06c6e2019-01-09 13:27:07 -08004314void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004315 const sp<InputWindowHandle>& newFocus) {
chaviw0c06c6e2019-01-09 13:27:07 -08004316 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4317 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004318 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4319 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004320 commandEntry->oldToken = oldToken;
4321 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004322 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004323}
4324
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004325void InputDispatcher::onANRLocked(nsecs_t currentTime,
4326 const sp<InputApplicationHandle>& applicationHandle,
4327 const sp<InputWindowHandle>& windowHandle, nsecs_t eventTime,
4328 nsecs_t waitStartTime, const char* reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004329 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4330 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4331 ALOGI("Application is not responding: %s. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004332 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
4333 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), dispatchLatency,
4334 waitDuration, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004335
4336 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004337 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004338 struct tm tm;
4339 localtime_r(&t, &tm);
4340 char timestr[64];
4341 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4342 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004343 mLastANRState += INDENT "ANR:\n";
4344 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004345 mLastANRState +=
4346 StringPrintf(INDENT2 "Window: %s\n",
4347 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004348 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4349 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4350 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004351 dumpDispatchStateLocked(mLastANRState);
4352
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004353 std::unique_ptr<CommandEntry> commandEntry =
4354 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004355 commandEntry->inputApplicationHandle = applicationHandle;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004356 commandEntry->inputChannel =
4357 windowHandle != nullptr ? getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004358 commandEntry->reason = reason;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004359 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004360}
4361
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004362void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004363 mLock.unlock();
4364
4365 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4366
4367 mLock.lock();
4368}
4369
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004370void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004371 sp<Connection> connection = commandEntry->connection;
4372
4373 if (connection->status != Connection::STATUS_ZOMBIE) {
4374 mLock.unlock();
4375
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004376 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004377
4378 mLock.lock();
4379 }
4380}
4381
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004382void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004383 sp<IBinder> oldToken = commandEntry->oldToken;
4384 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004385 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004386 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004387 mLock.lock();
4388}
4389
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004390void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004391 sp<IBinder> token =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004392 commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004393 mLock.unlock();
4394
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004395 nsecs_t newTimeout =
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004396 mPolicy->notifyANR(commandEntry->inputApplicationHandle, token, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004397
4398 mLock.lock();
4399
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004400 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004401}
4402
4403void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4404 CommandEntry* commandEntry) {
4405 KeyEntry* entry = commandEntry->keyEntry;
4406
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004407 KeyEvent event = createKeyEvent(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004408
4409 mLock.unlock();
4410
Michael Wright2b3c3302018-03-02 17:19:13 +00004411 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004412 sp<IBinder> token = commandEntry->inputChannel != nullptr
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004413 ? commandEntry->inputChannel->getConnectionToken()
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004414 : nullptr;
4415 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004416 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4417 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004418 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004419 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004420
4421 mLock.lock();
4422
4423 if (delay < 0) {
4424 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4425 } else if (!delay) {
4426 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4427 } else {
4428 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4429 entry->interceptKeyWakeupTime = now() + delay;
4430 }
4431 entry->release();
4432}
4433
chaviwfd6d3512019-03-25 13:23:49 -07004434void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4435 mLock.unlock();
4436 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4437 mLock.lock();
4438}
4439
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004440void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004441 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004442 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004443 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004444 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004445
4446 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07004447 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004448 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004449 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004450 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004451 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004452
4453 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4454 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4455 std::string msg =
4456 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4457 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4458 dispatchEntry->eventEntry->appendDescription(msg);
4459 ALOGI("%s", msg.c_str());
4460 }
4461
4462 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004463 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004464 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4465 restartEvent =
4466 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004467 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004468 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4469 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4470 handled);
4471 } else {
4472 restartEvent = false;
4473 }
4474
4475 // Dequeue the event and start the next cycle.
4476 // Note that because the lock might have been released, it is possible that the
4477 // contents of the wait queue to have been drained, so we need to double-check
4478 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004479 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4480 if (dispatchEntryIt != connection->waitQueue.end()) {
4481 dispatchEntry = *dispatchEntryIt;
4482 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004483 traceWaitQueueLength(connection);
4484 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004485 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004486 traceOutboundQueueLength(connection);
4487 } else {
4488 releaseDispatchEntry(dispatchEntry);
4489 }
4490 }
4491
4492 // Start the next dispatch cycle for this connection.
4493 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004494}
4495
4496bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004497 DispatchEntry* dispatchEntry,
4498 KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004499 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004500 if (!handled) {
4501 // Report the key as unhandled, since the fallback was not handled.
4502 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4503 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004504 return false;
4505 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004506
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004507 // Get the fallback key state.
4508 // Clear it out after dispatching the UP.
4509 int32_t originalKeyCode = keyEntry->keyCode;
4510 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4511 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4512 connection->inputState.removeFallbackKey(originalKeyCode);
4513 }
4514
4515 if (handled || !dispatchEntry->hasForegroundTarget()) {
4516 // If the application handles the original key for which we previously
4517 // generated a fallback or if the window is not a foreground window,
4518 // then cancel the associated fallback key, if any.
4519 if (fallbackKeyCode != -1) {
4520 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004521#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004522 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004523 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4524 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4525 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004526#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004527 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004528 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004529
4530 mLock.unlock();
4531
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004532 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004533 keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004534
4535 mLock.lock();
4536
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004537 // Cancel the fallback key.
4538 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004539 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004540 "application handled the original non-fallback key "
4541 "or is no longer a foreground target, "
4542 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004543 options.keyCode = fallbackKeyCode;
4544 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004545 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004546 connection->inputState.removeFallbackKey(originalKeyCode);
4547 }
4548 } else {
4549 // If the application did not handle a non-fallback key, first check
4550 // that we are in a good state to perform unhandled key event processing
4551 // Then ask the policy what to do with it.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004552 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN && keyEntry->repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004553 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004554#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004555 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004556 "since this is not an initial down. "
4557 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4558 originalKeyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004559#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004560 return false;
4561 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004562
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004563 // Dispatch the unhandled key to the policy.
4564#if DEBUG_OUTBOUND_EVENT_DETAILS
4565 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004566 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4567 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004568#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004569 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004570
4571 mLock.unlock();
4572
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004573 bool fallback =
4574 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
4575 &event, keyEntry->policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004576
4577 mLock.lock();
4578
4579 if (connection->status != Connection::STATUS_NORMAL) {
4580 connection->inputState.removeFallbackKey(originalKeyCode);
4581 return false;
4582 }
4583
4584 // Latch the fallback keycode for this key on an initial down.
4585 // The fallback keycode cannot change at any other point in the lifecycle.
4586 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004587 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004588 fallbackKeyCode = event.getKeyCode();
4589 } else {
4590 fallbackKeyCode = AKEYCODE_UNKNOWN;
4591 }
4592 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4593 }
4594
4595 ALOG_ASSERT(fallbackKeyCode != -1);
4596
4597 // Cancel the fallback key if the policy decides not to send it anymore.
4598 // We will continue to dispatch the key to the policy but we will no
4599 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004600 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
4601 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004602#if DEBUG_OUTBOUND_EVENT_DETAILS
4603 if (fallback) {
4604 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004605 "as a fallback for %d, but on the DOWN it had requested "
4606 "to send %d instead. Fallback canceled.",
4607 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004608 } else {
4609 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004610 "but on the DOWN it had requested to send %d. "
4611 "Fallback canceled.",
4612 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004613 }
4614#endif
4615
4616 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4617 "canceling fallback, policy no longer desires it");
4618 options.keyCode = fallbackKeyCode;
4619 synthesizeCancelationEventsForConnectionLocked(connection, options);
4620
4621 fallback = false;
4622 fallbackKeyCode = AKEYCODE_UNKNOWN;
4623 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004624 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004625 }
4626 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004627
4628#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004629 {
4630 std::string msg;
4631 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4632 connection->inputState.getFallbackKeys();
4633 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004634 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004635 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004636 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004637 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004638 }
4639#endif
4640
4641 if (fallback) {
4642 // Restart the dispatch cycle using the fallback key.
4643 keyEntry->eventTime = event.getEventTime();
4644 keyEntry->deviceId = event.getDeviceId();
4645 keyEntry->source = event.getSource();
4646 keyEntry->displayId = event.getDisplayId();
4647 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4648 keyEntry->keyCode = fallbackKeyCode;
4649 keyEntry->scanCode = event.getScanCode();
4650 keyEntry->metaState = event.getMetaState();
4651 keyEntry->repeatCount = event.getRepeatCount();
4652 keyEntry->downTime = event.getDownTime();
4653 keyEntry->syntheticRepeat = false;
4654
4655#if DEBUG_OUTBOUND_EVENT_DETAILS
4656 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004657 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4658 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004659#endif
4660 return true; // restart the event
4661 } else {
4662#if DEBUG_OUTBOUND_EVENT_DETAILS
4663 ALOGD("Unhandled key event: No fallback key.");
4664#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004665
4666 // Report the key as unhandled, since there is no fallback key.
4667 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004668 }
4669 }
4670 return false;
4671}
4672
4673bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004674 DispatchEntry* dispatchEntry,
4675 MotionEntry* motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004676 return false;
4677}
4678
4679void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4680 mLock.unlock();
4681
4682 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4683
4684 mLock.lock();
4685}
4686
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004687KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
4688 KeyEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06004689 event.initialize(entry.deviceId, entry.source, entry.displayId, INVALID_HMAC, entry.action,
4690 entry.flags, entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount,
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004691 entry.downTime, entry.eventTime);
4692 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004693}
4694
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004695void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004696 int32_t injectionResult,
4697 nsecs_t timeSpentWaitingForApplication) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004698 // TODO Write some statistics about how long we spend waiting.
4699}
4700
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05004701/**
4702 * Report the touch event latency to the statsd server.
4703 * Input events are reported for statistics if:
4704 * - This is a touchscreen event
4705 * - InputFilter is not enabled
4706 * - Event is not injected or synthesized
4707 *
4708 * Statistics should be reported before calling addValue, to prevent a fresh new sample
4709 * from getting aggregated with the "old" data.
4710 */
4711void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
4712 REQUIRES(mLock) {
4713 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
4714 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
4715 if (!reportForStatistics) {
4716 return;
4717 }
4718
4719 if (mTouchStatistics.shouldReport()) {
4720 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
4721 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
4722 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
4723 mTouchStatistics.reset();
4724 }
4725 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
4726 mTouchStatistics.addValue(latencyMicros);
4727}
4728
Michael Wrightd02c5b62014-02-10 15:10:22 -08004729void InputDispatcher::traceInboundQueueLengthLocked() {
4730 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004731 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004732 }
4733}
4734
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004735void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004736 if (ATRACE_ENABLED()) {
4737 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004738 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004739 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004740 }
4741}
4742
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004743void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004744 if (ATRACE_ENABLED()) {
4745 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004746 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004747 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004748 }
4749}
4750
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004751void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004752 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004753
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004754 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004755 dumpDispatchStateLocked(dump);
4756
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004757 if (!mLastANRState.empty()) {
4758 dump += "\nInput Dispatcher State at time of last ANR:\n";
4759 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004760 }
4761}
4762
4763void InputDispatcher::monitor() {
4764 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004765 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004766 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004767 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004768}
4769
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08004770/**
4771 * Wake up the dispatcher and wait until it processes all events and commands.
4772 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
4773 * this method can be safely called from any thread, as long as you've ensured that
4774 * the work you are interested in completing has already been queued.
4775 */
4776bool InputDispatcher::waitForIdle() {
4777 /**
4778 * Timeout should represent the longest possible time that a device might spend processing
4779 * events and commands.
4780 */
4781 constexpr std::chrono::duration TIMEOUT = 100ms;
4782 std::unique_lock lock(mLock);
4783 mLooper->wake();
4784 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
4785 return result == std::cv_status::no_timeout;
4786}
4787
Garfield Tane84e6f92019-08-29 17:28:41 -07004788} // namespace android::inputdispatcher