blob: 39b959557140e8cc75eaa805e6b003fa85625492 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
31// Log debug messages about registrations.
32#define DEBUG_REGISTRATION 0
33
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
Siarhei Vishniakou86587282019-09-09 18:20:15 +010038static constexpr bool DEBUG_FOCUS = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -080039
40// Log debug messages about the app switch latency optimization.
41#define DEBUG_APP_SWITCH 0
42
43// Log debug messages about hover events.
44#define DEBUG_HOVER 0
45
46#include "InputDispatcher.h"
47
Garfield Tane84e6f92019-08-29 17:28:41 -070048#include "Connection.h"
49
Michael Wrightd02c5b62014-02-10 15:10:22 -080050#include <errno.h>
Siarhei Vishniakou443ad902019-03-06 17:25:41 -080051#include <inttypes.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080052#include <limits.h>
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -050053#include <statslog.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070054#include <stddef.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080055#include <time.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070056#include <unistd.h>
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -070057#include <queue>
58#include <sstream>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070059
Michael Wright2b3c3302018-03-02 17:19:13 +000060#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080061#include <android-base/stringprintf.h>
Robert Carr4e670e52018-08-15 13:26:12 -070062#include <binder/Binder.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070063#include <log/log.h>
64#include <powermanager/PowerManager.h>
65#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080066
67#define INDENT " "
68#define INDENT2 " "
69#define INDENT3 " "
70#define INDENT4 " "
71
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080072using android::base::StringPrintf;
73
Garfield Tane84e6f92019-08-29 17:28:41 -070074namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080075
76// Default input dispatching timeout if there is no focused application or paused window
77// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000078constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080079
80// Amount of time to allow for all pending events to be processed when an app switch
81// key is on the way. This is used to preempt input dispatch and drop input events
82// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000083constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080084
85// Amount of time to allow for an event to be dispatched (measured since its eventTime)
86// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000087constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080088
89// Amount of time to allow touch events to be streamed out to a connection before requiring
90// that the first event be finished. This value extends the ANR timeout by the specified
91// amount. For example, if streaming is allowed to get ahead by one second relative to the
92// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000093constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080094
95// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +000096constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
97
98// Log a warning when an interception call takes longer than this to process.
99constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800100
101// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000102constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
103
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104static inline nsecs_t now() {
105 return systemTime(SYSTEM_TIME_MONOTONIC);
106}
107
108static inline const char* toString(bool value) {
109 return value ? "true" : "false";
110}
111
112static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700113 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
114 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115}
116
117static bool isValidKeyAction(int32_t action) {
118 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700119 case AKEY_EVENT_ACTION_DOWN:
120 case AKEY_EVENT_ACTION_UP:
121 return true;
122 default:
123 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800124 }
125}
126
127static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700128 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800129 ALOGE("Key event has invalid action code 0x%x", action);
130 return false;
131 }
132 return true;
133}
134
Michael Wright7b159c92015-05-14 14:48:03 +0100135static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800136 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700137 case AMOTION_EVENT_ACTION_DOWN:
138 case AMOTION_EVENT_ACTION_UP:
139 case AMOTION_EVENT_ACTION_CANCEL:
140 case AMOTION_EVENT_ACTION_MOVE:
141 case AMOTION_EVENT_ACTION_OUTSIDE:
142 case AMOTION_EVENT_ACTION_HOVER_ENTER:
143 case AMOTION_EVENT_ACTION_HOVER_MOVE:
144 case AMOTION_EVENT_ACTION_HOVER_EXIT:
145 case AMOTION_EVENT_ACTION_SCROLL:
146 return true;
147 case AMOTION_EVENT_ACTION_POINTER_DOWN:
148 case AMOTION_EVENT_ACTION_POINTER_UP: {
149 int32_t index = getMotionEventActionPointerIndex(action);
150 return index >= 0 && index < pointerCount;
151 }
152 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
153 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
154 return actionButton != 0;
155 default:
156 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800157 }
158}
159
Michael Wright7b159c92015-05-14 14:48:03 +0100160static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700161 const PointerProperties* pointerProperties) {
162 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800163 ALOGE("Motion event has invalid action code 0x%x", action);
164 return false;
165 }
166 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000167 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700168 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800169 return false;
170 }
171 BitSet32 pointerIdBits;
172 for (size_t i = 0; i < pointerCount; i++) {
173 int32_t id = pointerProperties[i].id;
174 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700175 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
176 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800177 return false;
178 }
179 if (pointerIdBits.hasBit(id)) {
180 ALOGE("Motion event has duplicate pointer id %d", id);
181 return false;
182 }
183 pointerIdBits.markBit(id);
184 }
185 return true;
186}
187
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800188static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800189 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800190 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800191 return;
192 }
193
194 bool first = true;
195 Region::const_iterator cur = region.begin();
196 Region::const_iterator const tail = region.end();
197 while (cur != tail) {
198 if (first) {
199 first = false;
200 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800201 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800202 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800203 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 cur++;
205 }
206}
207
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700208/**
209 * Find the entry in std::unordered_map by key, and return it.
210 * If the entry is not found, return a default constructed entry.
211 *
212 * Useful when the entries are vectors, since an empty vector will be returned
213 * if the entry is not found.
214 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
215 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700216template <typename K, typename V>
217static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700218 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700219 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800220}
221
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700222/**
223 * Find the entry in std::unordered_map by value, and remove it.
224 * If more than one entry has the same value, then all matching
225 * key-value pairs will be removed.
226 *
227 * Return true if at least one value has been removed.
228 */
229template <typename K, typename V>
230static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
231 bool removed = false;
232 for (auto it = map.begin(); it != map.end();) {
233 if (it->second == value) {
234 it = map.erase(it);
235 removed = true;
236 } else {
237 it++;
238 }
239 }
240 return removed;
241}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800242
chaviwaf87b3e2019-10-01 16:59:28 -0700243static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
244 if (first == second) {
245 return true;
246 }
247
248 if (first == nullptr || second == nullptr) {
249 return false;
250 }
251
252 return first->getToken() == second->getToken();
253}
254
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800255static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
256 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
257}
258
Chavi Weingarten97b8eec2020-01-09 18:09:08 +0000259static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
260 EventEntry* eventEntry,
261 int32_t inputTargetFlags) {
262 if (inputTarget.useDefaultPointerInfo()) {
263 const PointerInfo& pointerInfo = inputTarget.getDefaultPointerInfo();
264 return std::make_unique<DispatchEntry>(eventEntry, // increments ref
265 inputTargetFlags, pointerInfo.xOffset,
266 pointerInfo.yOffset, inputTarget.globalScaleFactor,
267 pointerInfo.windowXScale, pointerInfo.windowYScale);
268 }
269
270 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
271 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
272
273 PointerCoords pointerCoords[MAX_POINTERS];
274
275 // Use the first pointer information to normalize all other pointers. This could be any pointer
276 // as long as all other pointers are normalized to the same value and the final DispatchEntry
277 // uses the offset and scale for the normalized pointer.
278 const PointerInfo& firstPointerInfo =
279 inputTarget.pointerInfos[inputTarget.pointerIds.firstMarkedBit()];
280
281 // Iterate through all pointers in the event to normalize against the first.
282 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
283 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
284 uint32_t pointerId = uint32_t(pointerProperties.id);
285 const PointerInfo& currPointerInfo = inputTarget.pointerInfos[pointerId];
286
287 // The scale factor is the ratio of the current pointers scale to the normalized scale.
288 float scaleXDiff = currPointerInfo.windowXScale / firstPointerInfo.windowXScale;
289 float scaleYDiff = currPointerInfo.windowYScale / firstPointerInfo.windowYScale;
290
291 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
292 // First apply the current pointers offset to set the window at 0,0
293 pointerCoords[pointerIndex].applyOffset(currPointerInfo.xOffset, currPointerInfo.yOffset);
294 // Next scale the coordinates.
295 pointerCoords[pointerIndex].scale(1, scaleXDiff, scaleYDiff);
296 // Lastly, offset the coordinates so they're in the normalized pointer's frame.
297 pointerCoords[pointerIndex].applyOffset(-firstPointerInfo.xOffset,
298 -firstPointerInfo.yOffset);
299 }
300
301 MotionEntry* combinedMotionEntry =
302 new MotionEntry(motionEntry.sequenceNum, motionEntry.eventTime, motionEntry.deviceId,
303 motionEntry.source, motionEntry.displayId, motionEntry.policyFlags,
304 motionEntry.action, motionEntry.actionButton, motionEntry.flags,
305 motionEntry.metaState, motionEntry.buttonState,
306 motionEntry.classification, motionEntry.edgeFlags,
307 motionEntry.xPrecision, motionEntry.yPrecision,
308 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
309 motionEntry.downTime, motionEntry.pointerCount,
310 motionEntry.pointerProperties, pointerCoords, 0 /* xOffset */,
311 0 /* yOffset */);
312
313 return std::make_unique<DispatchEntry>(combinedMotionEntry, // increments ref
314 inputTargetFlags, firstPointerInfo.xOffset,
315 firstPointerInfo.yOffset, inputTarget.globalScaleFactor,
316 firstPointerInfo.windowXScale,
317 firstPointerInfo.windowYScale);
318}
319
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700320// --- InputDispatcherThread ---
321
322class InputDispatcher::InputDispatcherThread : public Thread {
323public:
324 explicit InputDispatcherThread(InputDispatcher* dispatcher)
325 : Thread(/* canCallJava */ true), mDispatcher(dispatcher) {}
326
327 ~InputDispatcherThread() {}
328
329private:
330 InputDispatcher* mDispatcher;
331
332 virtual bool threadLoop() override {
333 mDispatcher->dispatchOnce();
334 return true;
335 }
336};
337
Michael Wrightd02c5b62014-02-10 15:10:22 -0800338// --- InputDispatcher ---
339
Garfield Tan00f511d2019-06-12 16:55:40 -0700340InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
341 : mPolicy(policy),
342 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700343 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tan00f511d2019-06-12 16:55:40 -0700344 mAppSwitchSawKeyDown(false),
345 mAppSwitchDueTime(LONG_LONG_MAX),
346 mNextUnblockedEvent(nullptr),
347 mDispatchEnabled(false),
348 mDispatchFrozen(false),
349 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800350 // mInTouchMode will be initialized by the WindowManager to the default device config.
351 // To avoid leaking stack in case that call never comes, and for tests,
352 // initialize it here anyways.
353 mInTouchMode(true),
Garfield Tan00f511d2019-06-12 16:55:40 -0700354 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
355 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800356 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800357 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800358
Yi Kong9b14ac62018-07-17 13:48:38 -0700359 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800360
361 policy->getDispatcherConfiguration(&mConfig);
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700362
363 mThread = new InputDispatcherThread(this);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800364}
365
366InputDispatcher::~InputDispatcher() {
367 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800368 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800369
370 resetKeyRepeatLocked();
371 releasePendingEventLocked();
372 drainInboundQueueLocked();
373 }
374
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700375 while (!mConnectionsByFd.empty()) {
376 sp<Connection> connection = mConnectionsByFd.begin()->second;
377 unregisterInputChannel(connection->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800378 }
379}
380
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700381status_t InputDispatcher::start() {
382 if (mThread->isRunning()) {
383 return ALREADY_EXISTS;
384 }
385 return mThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
386}
387
388status_t InputDispatcher::stop() {
389 if (!mThread->isRunning()) {
390 return OK;
391 }
392 if (gettid() == mThread->getTid()) {
393 ALOGE("InputDispatcher can only be stopped from outside of the InputDispatcherThread!");
394 return INVALID_OPERATION;
395 }
396 // Directly calling requestExitAndWait() causes the thread to not exit
397 // if mLooper is waiting for a long timeout.
398 mThread->requestExit();
399 mLooper->wake();
400 return mThread->requestExitAndWait();
401}
402
Michael Wrightd02c5b62014-02-10 15:10:22 -0800403void InputDispatcher::dispatchOnce() {
404 nsecs_t nextWakeupTime = LONG_LONG_MAX;
405 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800406 std::scoped_lock _l(mLock);
407 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800408
409 // Run a dispatch loop if there are no pending commands.
410 // The dispatch loop might enqueue commands to run afterwards.
411 if (!haveCommandsLocked()) {
412 dispatchOnceInnerLocked(&nextWakeupTime);
413 }
414
415 // Run all pending commands if there are any.
416 // If any commands were run then force the next poll to wake up immediately.
417 if (runCommandsLockedInterruptible()) {
418 nextWakeupTime = LONG_LONG_MIN;
419 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800420
421 // We are about to enter an infinitely long sleep, because we have no commands or
422 // pending or queued events
423 if (nextWakeupTime == LONG_LONG_MAX) {
424 mDispatcherEnteredIdle.notify_all();
425 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800426 } // release lock
427
428 // Wait for callback or timeout or wake. (make sure we round up, not down)
429 nsecs_t currentTime = now();
430 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
431 mLooper->pollOnce(timeoutMillis);
432}
433
434void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
435 nsecs_t currentTime = now();
436
Jeff Browndc5992e2014-04-11 01:27:26 -0700437 // Reset the key repeat timer whenever normal dispatch is suspended while the
438 // device is in a non-interactive state. This is to ensure that we abort a key
439 // repeat if the device is just coming out of sleep.
440 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800441 resetKeyRepeatLocked();
442 }
443
444 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
445 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100446 if (DEBUG_FOCUS) {
447 ALOGD("Dispatch frozen. Waiting some more.");
448 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800449 return;
450 }
451
452 // Optimize latency of app switches.
453 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
454 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
455 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
456 if (mAppSwitchDueTime < *nextWakeupTime) {
457 *nextWakeupTime = mAppSwitchDueTime;
458 }
459
460 // Ready to start a new event.
461 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700462 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700463 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800464 if (isAppSwitchDue) {
465 // The inbound queue is empty so the app switch key we were waiting
466 // for will never arrive. Stop waiting for it.
467 resetPendingAppSwitchLocked(false);
468 isAppSwitchDue = false;
469 }
470
471 // Synthesize a key repeat if appropriate.
472 if (mKeyRepeatState.lastKeyEntry) {
473 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
474 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
475 } else {
476 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
477 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
478 }
479 }
480 }
481
482 // Nothing to do if there is no pending event.
483 if (!mPendingEvent) {
484 return;
485 }
486 } else {
487 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700488 mPendingEvent = mInboundQueue.front();
489 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800490 traceInboundQueueLengthLocked();
491 }
492
493 // Poke user activity for this event.
494 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700495 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800496 }
497
498 // Get ready to dispatch the event.
499 resetANRTimeoutsLocked();
500 }
501
502 // Now we have an event to dispatch.
503 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700504 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800505 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700506 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800507 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700508 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800509 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700510 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800511 }
512
513 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700514 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800515 }
516
517 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700518 case EventEntry::Type::CONFIGURATION_CHANGED: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700519 ConfigurationChangedEntry* typedEntry =
520 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
521 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700522 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700523 break;
524 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800525
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700526 case EventEntry::Type::DEVICE_RESET: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700527 DeviceResetEntry* typedEntry = static_cast<DeviceResetEntry*>(mPendingEvent);
528 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700529 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700530 break;
531 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800532
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100533 case EventEntry::Type::FOCUS: {
534 FocusEntry* typedEntry = static_cast<FocusEntry*>(mPendingEvent);
535 dispatchFocusLocked(currentTime, typedEntry);
536 done = true;
537 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
538 break;
539 }
540
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700541 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700542 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
543 if (isAppSwitchDue) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700544 if (isAppSwitchKeyEvent(*typedEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700545 resetPendingAppSwitchLocked(true);
546 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700547 } else if (dropReason == DropReason::NOT_DROPPED) {
548 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700549 }
550 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700551 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700552 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700553 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700554 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
555 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700556 }
557 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
558 break;
559 }
560
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700561 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700562 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700563 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
564 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800565 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700566 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700567 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700568 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700569 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
570 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700571 }
572 done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
573 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800574 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800575 }
576
577 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700578 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700579 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800580 }
Michael Wright3a981722015-06-10 15:26:13 +0100581 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800582
583 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700584 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800585 }
586}
587
588bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700589 bool needWake = mInboundQueue.empty();
590 mInboundQueue.push_back(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800591 traceInboundQueueLengthLocked();
592
593 switch (entry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700594 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700595 // Optimize app switch latency.
596 // If the application takes too long to catch up then we drop all events preceding
597 // the app switch key.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700598 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700599 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700600 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700601 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700602 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700603 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800604#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700605 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800606#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700607 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700608 mAppSwitchSawKeyDown = false;
609 needWake = true;
610 }
611 }
612 }
613 break;
614 }
615
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700616 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700617 // Optimize case where the current application is unresponsive and the user
618 // decides to touch a window in a different application.
619 // If the application takes too long to catch up then we drop all events preceding
620 // the touch into the other window.
621 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
622 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN &&
623 (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
624 mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY &&
625 mInputTargetWaitApplicationToken != nullptr) {
626 int32_t displayId = motionEntry->displayId;
627 int32_t x =
628 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
629 int32_t y =
630 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
631 sp<InputWindowHandle> touchedWindowHandle =
632 findTouchedWindowAtLocked(displayId, x, y);
633 if (touchedWindowHandle != nullptr &&
634 touchedWindowHandle->getApplicationToken() !=
635 mInputTargetWaitApplicationToken) {
636 // User touched a different application than the one we are waiting on.
637 // Flag the event, and start pruning the input queue.
638 mNextUnblockedEvent = motionEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800639 needWake = true;
640 }
641 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700642 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800643 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700644 case EventEntry::Type::CONFIGURATION_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100645 case EventEntry::Type::DEVICE_RESET:
646 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700647 // nothing to do
648 break;
649 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800650 }
651
652 return needWake;
653}
654
655void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
656 entry->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700657 mRecentQueue.push_back(entry);
658 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
659 mRecentQueue.front()->release();
660 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800661 }
662}
663
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700664sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
665 int32_t y, bool addOutsideTargets,
666 bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800667 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800668 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
669 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800670 const InputWindowInfo* windowInfo = windowHandle->getInfo();
671 if (windowInfo->displayId == displayId) {
672 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800673
674 if (windowInfo->visible) {
675 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700676 bool isTouchModal = (flags &
677 (InputWindowInfo::FLAG_NOT_FOCUSABLE |
678 InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800679 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800680 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700681 if (portalToDisplayId != ADISPLAY_ID_NONE &&
682 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800683 if (addPortalWindows) {
684 // For the monitoring channels of the display.
685 mTempTouchState.addPortalWindow(windowHandle);
686 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700687 return findTouchedWindowAtLocked(portalToDisplayId, x, y,
688 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800689 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800690 // Found window.
691 return windowHandle;
692 }
693 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800694
695 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700696 mTempTouchState.addOrUpdateWindow(windowHandle,
697 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
698 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800699 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800700 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800701 }
702 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700703 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800704}
705
Garfield Tane84e6f92019-08-29 17:28:41 -0700706std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +0000707 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
708 std::vector<TouchedMonitor> touchedMonitors;
709
710 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
711 addGestureMonitors(monitors, touchedMonitors);
712 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
713 const InputWindowInfo* windowInfo = portalWindow->getInfo();
714 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700715 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
716 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000717 }
718 return touchedMonitors;
719}
720
721void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700722 std::vector<TouchedMonitor>& outTouchedMonitors,
723 float xOffset, float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000724 if (monitors.empty()) {
725 return;
726 }
727 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
728 for (const Monitor& monitor : monitors) {
729 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
730 }
731}
732
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700733void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800734 const char* reason;
735 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700736 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800737#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700738 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800739#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700740 reason = "inbound event was dropped because the policy consumed it";
741 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700742 case DropReason::DISABLED:
743 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700744 ALOGI("Dropped event because input dispatch is disabled.");
745 }
746 reason = "inbound event was dropped because input dispatch is disabled";
747 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700748 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700749 ALOGI("Dropped event because of pending overdue app switch.");
750 reason = "inbound event was dropped because of pending overdue app switch";
751 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700752 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700753 ALOGI("Dropped event because the current application is not responding and the user "
754 "has started interacting with a different application.");
755 reason = "inbound event was dropped because the current application is not responding "
756 "and the user has started interacting with a different application";
757 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700758 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700759 ALOGI("Dropped event because it is stale.");
760 reason = "inbound event was dropped because it is stale";
761 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700762 case DropReason::NOT_DROPPED: {
763 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700764 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700765 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800766 }
767
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700768 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700769 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800770 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
771 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700772 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800773 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700774 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700775 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
776 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700777 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
778 synthesizeCancelationEventsForAllConnectionsLocked(options);
779 } else {
780 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
781 synthesizeCancelationEventsForAllConnectionsLocked(options);
782 }
783 break;
784 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100785 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700786 case EventEntry::Type::CONFIGURATION_CHANGED:
787 case EventEntry::Type::DEVICE_RESET: {
788 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
789 break;
790 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800791 }
792}
793
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800794static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700795 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
796 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800797}
798
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700799bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
800 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
801 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
802 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800803}
804
805bool InputDispatcher::isAppSwitchPendingLocked() {
806 return mAppSwitchDueTime != LONG_LONG_MAX;
807}
808
809void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
810 mAppSwitchDueTime = LONG_LONG_MAX;
811
812#if DEBUG_APP_SWITCH
813 if (handled) {
814 ALOGD("App switch has arrived.");
815 } else {
816 ALOGD("App switch was abandoned.");
817 }
818#endif
819}
820
Michael Wrightd02c5b62014-02-10 15:10:22 -0800821bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700822 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800823}
824
825bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700826 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800827 return false;
828 }
829
830 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700831 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700832 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800833 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700834 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800835
836 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700837 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800838 return true;
839}
840
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700841void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
842 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800843}
844
845void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700846 while (!mInboundQueue.empty()) {
847 EventEntry* entry = mInboundQueue.front();
848 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800849 releaseInboundEventLocked(entry);
850 }
851 traceInboundQueueLengthLocked();
852}
853
854void InputDispatcher::releasePendingEventLocked() {
855 if (mPendingEvent) {
856 resetANRTimeoutsLocked();
857 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700858 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800859 }
860}
861
862void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
863 InjectionState* injectionState = entry->injectionState;
864 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
865#if DEBUG_DISPATCH_CYCLE
866 ALOGD("Injected inbound event was dropped.");
867#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800868 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800869 }
870 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700871 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800872 }
873 addRecentEventLocked(entry);
874 entry->release();
875}
876
877void InputDispatcher::resetKeyRepeatLocked() {
878 if (mKeyRepeatState.lastKeyEntry) {
879 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700880 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800881 }
882}
883
Garfield Tane84e6f92019-08-29 17:28:41 -0700884KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800885 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
886
887 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700888 uint32_t policyFlags = entry->policyFlags &
889 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800890 if (entry->refCount == 1) {
891 entry->recycle();
892 entry->eventTime = currentTime;
893 entry->policyFlags = policyFlags;
894 entry->repeatCount += 1;
895 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700896 KeyEntry* newEntry =
897 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, entry->deviceId,
898 entry->source, entry->displayId, policyFlags, entry->action,
899 entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
900 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800901
902 mKeyRepeatState.lastKeyEntry = newEntry;
903 entry->release();
904
905 entry = newEntry;
906 }
907 entry->syntheticRepeat = true;
908
909 // Increment reference count since we keep a reference to the event in
910 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
911 entry->refCount += 1;
912
913 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
914 return entry;
915}
916
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700917bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
918 ConfigurationChangedEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800919#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700920 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800921#endif
922
923 // Reset key repeating in case a keyboard device was added or removed or something.
924 resetKeyRepeatLocked();
925
926 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700927 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
928 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800929 commandEntry->eventTime = entry->eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700930 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800931 return true;
932}
933
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700934bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceResetEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800935#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700936 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700937 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800938#endif
939
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700940 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800941 options.deviceId = entry->deviceId;
942 synthesizeCancelationEventsForAllConnectionsLocked(options);
943 return true;
944}
945
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100946void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) {
947 FocusEntry* focusEntry =
948 new FocusEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, now(), window.getToken(), hasFocus);
949 enqueueInboundEventLocked(focusEntry);
950}
951
952void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) {
953 sp<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
954 if (channel == nullptr) {
955 return; // Window has gone away
956 }
957 InputTarget target;
958 target.inputChannel = channel;
959 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
960 entry->dispatchInProgress = true;
961
962 dispatchEventLocked(currentTime, entry, {target});
963}
964
Michael Wrightd02c5b62014-02-10 15:10:22 -0800965bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700966 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800967 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700968 if (!entry->dispatchInProgress) {
969 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
970 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
971 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
972 if (mKeyRepeatState.lastKeyEntry &&
973 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800974 // We have seen two identical key downs in a row which indicates that the device
975 // driver is automatically generating key repeats itself. We take note of the
976 // repeat here, but we disable our own next key repeat timer since it is clear that
977 // we will not need to synthesize key repeats ourselves.
978 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
979 resetKeyRepeatLocked();
980 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
981 } else {
982 // Not a repeat. Save key down state in case we do see a repeat later.
983 resetKeyRepeatLocked();
984 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
985 }
986 mKeyRepeatState.lastKeyEntry = entry;
987 entry->refCount += 1;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700988 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800989 resetKeyRepeatLocked();
990 }
991
992 if (entry->repeatCount == 1) {
993 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
994 } else {
995 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
996 }
997
998 entry->dispatchInProgress = true;
999
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001000 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001001 }
1002
1003 // Handle case where the policy asked us to try again later last time.
1004 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1005 if (currentTime < entry->interceptKeyWakeupTime) {
1006 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1007 *nextWakeupTime = entry->interceptKeyWakeupTime;
1008 }
1009 return false; // wait until next wakeup
1010 }
1011 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1012 entry->interceptKeyWakeupTime = 0;
1013 }
1014
1015 // Give the policy a chance to intercept the key.
1016 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1017 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001018 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001019 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +08001020 sp<InputWindowHandle> focusedWindowHandle =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001021 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(*entry));
Tiger Huang721e26f2018-07-24 22:26:19 +08001022 if (focusedWindowHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001023 commandEntry->inputChannel = getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001024 }
1025 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001026 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001027 entry->refCount += 1;
1028 return false; // wait for the command to run
1029 } else {
1030 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1031 }
1032 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001033 if (*dropReason == DropReason::NOT_DROPPED) {
1034 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001035 }
1036 }
1037
1038 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001039 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001040 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001041 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001042 : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08001043 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001044 return true;
1045 }
1046
1047 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001048 std::vector<InputTarget> inputTargets;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001049 int32_t injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001050 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001051 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1052 return false;
1053 }
1054
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001055 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001056 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
1057 return true;
1058 }
1059
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001060 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001061 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001062
1063 // Dispatch the key.
1064 dispatchEventLocked(currentTime, entry, inputTargets);
1065 return true;
1066}
1067
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001068void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001069#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001070 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001071 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1072 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001073 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1074 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1075 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001076#endif
1077}
1078
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001079bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry,
1080 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001081 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001082 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001083 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001084 entry->dispatchInProgress = true;
1085
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001086 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001087 }
1088
1089 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001090 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001091 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001092 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001093 : INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001094 return true;
1095 }
1096
1097 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1098
1099 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001100 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001101
1102 bool conflictingPointerActions = false;
1103 int32_t injectionResult;
1104 if (isPointerEvent) {
1105 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001106 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001107 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001108 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001109 } else {
1110 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001111 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001112 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001113 }
1114 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1115 return false;
1116 }
1117
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001118 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001119 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001120 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001121 CancelationOptions::Mode mode(isPointerEvent
1122 ? CancelationOptions::CANCEL_POINTER_EVENTS
1123 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001124 CancelationOptions options(mode, "input event injection failed");
1125 synthesizeCancelationEventsForMonitorsLocked(options);
1126 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001127 return true;
1128 }
1129
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001130 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001131 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001132
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001133 if (isPointerEvent) {
1134 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1135 if (stateIndex >= 0) {
1136 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001137 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001138 // The event has gone through these portal windows, so we add monitoring targets of
1139 // the corresponding displays as well.
1140 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001141 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001142 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001143 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001144 }
1145 }
1146 }
1147 }
1148
Michael Wrightd02c5b62014-02-10 15:10:22 -08001149 // Dispatch the motion.
1150 if (conflictingPointerActions) {
1151 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001152 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001153 synthesizeCancelationEventsForAllConnectionsLocked(options);
1154 }
1155 dispatchEventLocked(currentTime, entry, inputTargets);
1156 return true;
1157}
1158
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001159void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001160#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001161 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001162 ", policyFlags=0x%x, "
1163 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1164 "metaState=0x%x, buttonState=0x%x,"
1165 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001166 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1167 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1168 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001169
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001170 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001171 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001172 "x=%f, y=%f, pressure=%f, size=%f, "
1173 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1174 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001175 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1176 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1177 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1178 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1179 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1180 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1181 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1182 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1183 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1184 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001185 }
1186#endif
1187}
1188
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001189void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* eventEntry,
1190 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001191 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001192#if DEBUG_DISPATCH_CYCLE
1193 ALOGD("dispatchEventToCurrentInputTargets");
1194#endif
1195
1196 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1197
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001198 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001199
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001200 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001201 sp<Connection> connection =
1202 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001203 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001204 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001205 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001206 if (DEBUG_FOCUS) {
1207 ALOGD("Dropping event delivery to target with channel '%s' because it "
1208 "is no longer registered with the input dispatcher.",
1209 inputTarget.inputChannel->getName().c_str());
1210 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001211 }
1212 }
1213}
1214
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001215int32_t InputDispatcher::handleTargetsNotReadyLocked(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001216 nsecs_t currentTime, const EventEntry& entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001217 const sp<InputApplicationHandle>& applicationHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001218 const sp<InputWindowHandle>& windowHandle, nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001219 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001220 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001221 if (DEBUG_FOCUS) {
1222 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1223 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001224 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1225 mInputTargetWaitStartTime = currentTime;
1226 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1227 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001228 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001229 }
1230 } else {
1231 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001232 if (DEBUG_FOCUS) {
1233 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
1234 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), reason);
1235 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001236 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001237 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001238 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001239 } else if (applicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001240 timeout =
1241 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001242 } else {
1243 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1244 }
1245
1246 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1247 mInputTargetWaitStartTime = currentTime;
1248 mInputTargetWaitTimeoutTime = currentTime + timeout;
1249 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001250 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001251
Yi Kong9b14ac62018-07-17 13:48:38 -07001252 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001253 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001254 }
Robert Carr740167f2018-10-11 19:03:41 -07001255 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1256 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001257 }
1258 }
1259 }
1260
1261 if (mInputTargetWaitTimeoutExpired) {
1262 return INPUT_EVENT_INJECTION_TIMED_OUT;
1263 }
1264
1265 if (currentTime >= mInputTargetWaitTimeoutTime) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001266 onANRLocked(currentTime, applicationHandle, windowHandle, entry.eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001267 mInputTargetWaitStartTime, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001268
1269 // Force poll loop to wake up immediately on next iteration once we get the
1270 // ANR response back from the policy.
1271 *nextWakeupTime = LONG_LONG_MIN;
1272 return INPUT_EVENT_INJECTION_PENDING;
1273 } else {
1274 // Force poll loop to wake up when timeout is due.
1275 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1276 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1277 }
1278 return INPUT_EVENT_INJECTION_PENDING;
1279 }
1280}
1281
Robert Carr803535b2018-08-02 16:38:15 -07001282void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1283 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1284 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1285 state.removeWindowByToken(token);
1286 }
1287}
1288
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001289void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001290 nsecs_t newTimeout, const sp<IBinder>& inputConnectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001291 if (newTimeout > 0) {
1292 // Extend the timeout.
1293 mInputTargetWaitTimeoutTime = now() + newTimeout;
1294 } else {
1295 // Give up.
1296 mInputTargetWaitTimeoutExpired = true;
1297
1298 // Input state will not be realistic. Mark it out of sync.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001299 sp<Connection> connection = getConnectionLocked(inputConnectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001300 if (connection != nullptr) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001301 removeWindowByTokenLocked(inputConnectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001302
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001303 if (connection->status == Connection::STATUS_NORMAL) {
1304 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1305 "application not responding");
1306 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001307 }
1308 }
1309 }
1310}
1311
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001312nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001313 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1314 return currentTime - mInputTargetWaitStartTime;
1315 }
1316 return 0;
1317}
1318
1319void InputDispatcher::resetANRTimeoutsLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001320 if (DEBUG_FOCUS) {
1321 ALOGD("Resetting ANR timeouts.");
1322 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001323
1324 // Reset input target wait timeout.
1325 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001326 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001327}
1328
Tiger Huang721e26f2018-07-24 22:26:19 +08001329/**
1330 * Get the display id that the given event should go to. If this event specifies a valid display id,
1331 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1332 * Focused display is the display that the user most recently interacted with.
1333 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001334int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001335 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001336 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001337 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001338 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1339 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001340 break;
1341 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001342 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001343 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1344 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001345 break;
1346 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001347 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001348 case EventEntry::Type::CONFIGURATION_CHANGED:
1349 case EventEntry::Type::DEVICE_RESET: {
1350 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001351 return ADISPLAY_ID_NONE;
1352 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001353 }
1354 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1355}
1356
Michael Wrightd02c5b62014-02-10 15:10:22 -08001357int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001358 const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001359 std::vector<InputTarget>& inputTargets,
1360 nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001361 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001362 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001363
Tiger Huang721e26f2018-07-24 22:26:19 +08001364 int32_t displayId = getTargetDisplayId(entry);
1365 sp<InputWindowHandle> focusedWindowHandle =
1366 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1367 sp<InputApplicationHandle> focusedApplicationHandle =
1368 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1369
Michael Wrightd02c5b62014-02-10 15:10:22 -08001370 // If there is no currently focused window and no focused application
1371 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001372 if (focusedWindowHandle == nullptr) {
1373 if (focusedApplicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001374 injectionResult =
1375 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1376 nullptr, nextWakeupTime,
1377 "Waiting because no window has focus but there is "
1378 "a focused application that may eventually add a "
1379 "window when it finishes starting up.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001380 goto Unresponsive;
1381 }
1382
Arthur Hung3b413f22018-10-26 18:05:34 +08001383 ALOGI("Dropping event because there is no focused window or focused application in display "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001384 "%" PRId32 ".",
1385 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001386 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1387 goto Failed;
1388 }
1389
1390 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001391 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001392 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1393 goto Failed;
1394 }
1395
Jeff Brownffb49772014-10-10 19:01:34 -07001396 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001397 reason = checkWindowReadyForMoreInputLocked(currentTime, focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001398 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001399 injectionResult =
1400 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1401 focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001402 goto Unresponsive;
1403 }
1404
1405 // Success! Output targets.
1406 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001407 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001408 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1409 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001410
1411 // Done.
1412Failed:
1413Unresponsive:
1414 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001415 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001416 if (DEBUG_FOCUS) {
1417 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1418 "timeSpentWaitingForApplication=%0.1fms",
1419 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1420 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001421 return injectionResult;
1422}
1423
1424int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001425 const MotionEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001426 std::vector<InputTarget>& inputTargets,
1427 nsecs_t* nextWakeupTime,
1428 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001429 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001430 enum InjectionPermission {
1431 INJECTION_PERMISSION_UNKNOWN,
1432 INJECTION_PERMISSION_GRANTED,
1433 INJECTION_PERMISSION_DENIED
1434 };
1435
Michael Wrightd02c5b62014-02-10 15:10:22 -08001436 // For security reasons, we defer updating the touch state until we are sure that
1437 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001438 int32_t displayId = entry.displayId;
1439 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001440 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1441
1442 // Update the touch state as needed based on the properties of the touch event.
1443 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1444 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1445 sp<InputWindowHandle> newHoverWindowHandle;
1446
Jeff Brownf086ddb2014-02-11 14:28:48 -08001447 // Copy current touch state into mTempTouchState.
1448 // This state is always reset at the end of this function, so if we don't find state
1449 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001450 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001451 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1452 if (oldStateIndex >= 0) {
1453 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1454 mTempTouchState.copyFrom(*oldState);
1455 }
1456
1457 bool isSplit = mTempTouchState.split;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001458 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0 &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001459 (mTempTouchState.deviceId != entry.deviceId || mTempTouchState.source != entry.source ||
1460 mTempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001461 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1462 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1463 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1464 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1465 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001466 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001467 bool wrongDevice = false;
1468 if (newGesture) {
1469 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001470 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001471 if (DEBUG_FOCUS) {
1472 ALOGD("Dropping event because a pointer for a different device is already down "
1473 "in display %" PRId32,
1474 displayId);
1475 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001476 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001477 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1478 switchedDevice = false;
1479 wrongDevice = true;
1480 goto Failed;
1481 }
1482 mTempTouchState.reset();
1483 mTempTouchState.down = down;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001484 mTempTouchState.deviceId = entry.deviceId;
1485 mTempTouchState.source = entry.source;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001486 mTempTouchState.displayId = displayId;
1487 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001488 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001489 if (DEBUG_FOCUS) {
1490 ALOGI("Dropping move event because a pointer for a different device is already active "
1491 "in display %" PRId32,
1492 displayId);
1493 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001494 // TODO: test multiple simultaneous input streams.
1495 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1496 switchedDevice = false;
1497 wrongDevice = true;
1498 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001499 }
1500
1501 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1502 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1503
Garfield Tan00f511d2019-06-12 16:55:40 -07001504 int32_t x;
1505 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001506 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001507 // Always dispatch mouse events to cursor position.
1508 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001509 x = int32_t(entry.xCursorPosition);
1510 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001511 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001512 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1513 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001514 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001515 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001516 sp<InputWindowHandle> newTouchedWindowHandle =
1517 findTouchedWindowAtLocked(displayId, x, y, isDown /*addOutsideTargets*/,
1518 true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001519
1520 std::vector<TouchedMonitor> newGestureMonitors = isDown
1521 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1522 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001523
Michael Wrightd02c5b62014-02-10 15:10:22 -08001524 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001525 if (newTouchedWindowHandle != nullptr &&
1526 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001527 // New window supports splitting, but we should never split mouse events.
1528 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001529 } else if (isSplit) {
1530 // New window does not support splitting but we have already split events.
1531 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001532 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001533 }
1534
1535 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001536 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001537 // Try to assign the pointer to the first foreground window we find, if there is one.
1538 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001539 }
1540
1541 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1542 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001543 "(%d, %d) in display %" PRId32 ".",
1544 x, y, displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00001545 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1546 goto Failed;
1547 }
1548
1549 if (newTouchedWindowHandle != nullptr) {
1550 // Set target flags.
1551 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1552 if (isSplit) {
1553 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001554 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001555 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1556 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1557 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1558 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1559 }
1560
1561 // Update hover state.
1562 if (isHoverAction) {
1563 newHoverWindowHandle = newTouchedWindowHandle;
1564 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1565 newHoverWindowHandle = mLastHoverWindowHandle;
1566 }
1567
1568 // Update the temporary touch state.
1569 BitSet32 pointerIds;
1570 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001571 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001572 pointerIds.markBit(pointerId);
1573 }
1574 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001575 }
1576
Michael Wright3dd60e22019-03-27 22:06:44 +00001577 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001578 } else {
1579 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1580
1581 // If the pointer is not currently down, then ignore the event.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001582 if (!mTempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001583 if (DEBUG_FOCUS) {
1584 ALOGD("Dropping event because the pointer is not down or we previously "
1585 "dropped the pointer down event in display %" PRId32,
1586 displayId);
1587 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001588 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1589 goto Failed;
1590 }
1591
1592 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001593 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001594 mTempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001595 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1596 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001597
1598 sp<InputWindowHandle> oldTouchedWindowHandle =
1599 mTempTouchState.getFirstForegroundWindowHandle();
1600 sp<InputWindowHandle> newTouchedWindowHandle =
1601 findTouchedWindowAtLocked(displayId, x, y);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001602 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1603 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001604 if (DEBUG_FOCUS) {
1605 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1606 oldTouchedWindowHandle->getName().c_str(),
1607 newTouchedWindowHandle->getName().c_str(), displayId);
1608 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001609 // Make a slippery exit from the old window.
1610 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001611 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1612 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001613
1614 // Make a slippery entrance into the new window.
1615 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1616 isSplit = true;
1617 }
1618
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001619 int32_t targetFlags =
1620 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001621 if (isSplit) {
1622 targetFlags |= InputTarget::FLAG_SPLIT;
1623 }
1624 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1625 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1626 }
1627
1628 BitSet32 pointerIds;
1629 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001630 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001631 }
1632 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1633 }
1634 }
1635 }
1636
1637 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1638 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001639 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001640#if DEBUG_HOVER
1641 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001642 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001643#endif
1644 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001645 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT,
1646 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001647 }
1648
1649 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001650 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001651#if DEBUG_HOVER
1652 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001653 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001654#endif
1655 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001656 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1657 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001658 }
1659 }
1660
1661 // Check permission to inject into all touched foreground windows and ensure there
1662 // is at least one touched foreground window.
1663 {
1664 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001665 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001666 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1667 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001668 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001669 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1670 injectionPermission = INJECTION_PERMISSION_DENIED;
1671 goto Failed;
1672 }
1673 }
1674 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001675 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1676 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001677 if (DEBUG_FOCUS) {
1678 ALOGD("Dropping event because there is no touched foreground window in display "
1679 "%" PRId32 " or gesture monitor to receive it.",
1680 displayId);
1681 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001682 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1683 goto Failed;
1684 }
1685
1686 // Permission granted to injection into all touched foreground windows.
1687 injectionPermission = INJECTION_PERMISSION_GRANTED;
1688 }
1689
1690 // Check whether windows listening for outside touches are owned by the same UID. If it is
1691 // set the policy flag that we will not reveal coordinate information to this window.
1692 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1693 sp<InputWindowHandle> foregroundWindowHandle =
1694 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001695 if (foregroundWindowHandle) {
1696 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1697 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1698 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1699 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1700 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1701 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001702 InputTarget::FLAG_ZERO_COORDS,
1703 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001704 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001705 }
1706 }
1707 }
1708 }
1709
1710 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001711 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001712 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001713 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001714 std::string reason =
1715 checkWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle,
1716 entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001717 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001718 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, nullptr,
1719 touchedWindow.windowHandle,
1720 nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001721 goto Unresponsive;
1722 }
1723 }
1724 }
1725
1726 // If this is the first pointer going down and the touched window has a wallpaper
1727 // then also add the touched wallpaper windows so they are locked in for the duration
1728 // of the touch gesture.
1729 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1730 // engine only supports touch events. We would need to add a mechanism similar
1731 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1732 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1733 sp<InputWindowHandle> foregroundWindowHandle =
1734 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001735 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001736 const std::vector<sp<InputWindowHandle>> windowHandles =
1737 getWindowHandlesLocked(displayId);
1738 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001739 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001740 if (info->displayId == displayId &&
1741 windowHandle->getInfo()->layoutParamsType == InputWindowInfo::TYPE_WALLPAPER) {
1742 mTempTouchState
1743 .addOrUpdateWindow(windowHandle,
1744 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1745 InputTarget::
1746 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1747 InputTarget::FLAG_DISPATCH_AS_IS,
1748 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001749 }
1750 }
1751 }
1752 }
1753
1754 // Success! Output targets.
1755 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1756
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001757 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001758 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001759 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001760 }
1761
Michael Wright3dd60e22019-03-27 22:06:44 +00001762 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1763 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001764 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00001765 }
1766
Michael Wrightd02c5b62014-02-10 15:10:22 -08001767 // Drop the outside or hover touch windows since we will not care about them
1768 // in the next iteration.
1769 mTempTouchState.filterNonAsIsTouchWindows();
1770
1771Failed:
1772 // Check injection permission once and for all.
1773 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001774 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001775 injectionPermission = INJECTION_PERMISSION_GRANTED;
1776 } else {
1777 injectionPermission = INJECTION_PERMISSION_DENIED;
1778 }
1779 }
1780
1781 // Update final pieces of touch state if the injector had permission.
1782 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1783 if (!wrongDevice) {
1784 if (switchedDevice) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001785 if (DEBUG_FOCUS) {
1786 ALOGD("Conflicting pointer actions: Switched to a different device.");
1787 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001788 *outConflictingPointerActions = true;
1789 }
1790
1791 if (isHoverAction) {
1792 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001793 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001794 if (DEBUG_FOCUS) {
1795 ALOGD("Conflicting pointer actions: Hover received while pointer was "
1796 "down.");
1797 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001798 *outConflictingPointerActions = true;
1799 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001800 mTempTouchState.reset();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001801 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1802 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001803 mTempTouchState.deviceId = entry.deviceId;
1804 mTempTouchState.source = entry.source;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001805 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001806 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001807 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
1808 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001809 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001810 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001811 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1812 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001813 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001814 if (DEBUG_FOCUS) {
1815 ALOGD("Conflicting pointer actions: Down received while already down.");
1816 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001817 *outConflictingPointerActions = true;
1818 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001819 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1820 // One pointer went up.
1821 if (isSplit) {
1822 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001823 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001824
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001825 for (size_t i = 0; i < mTempTouchState.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001826 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001827 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1828 touchedWindow.pointerIds.clearBit(pointerId);
1829 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001830 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001831 continue;
1832 }
1833 }
1834 i += 1;
1835 }
1836 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001837 }
1838
1839 // Save changes unless the action was scroll in which case the temporary touch
1840 // state was only valid for this one action.
1841 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1842 if (mTempTouchState.displayId >= 0) {
1843 if (oldStateIndex >= 0) {
1844 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1845 } else {
1846 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1847 }
1848 } else if (oldStateIndex >= 0) {
1849 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1850 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001851 }
1852
1853 // Update hover state.
1854 mLastHoverWindowHandle = newHoverWindowHandle;
1855 }
1856 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001857 if (DEBUG_FOCUS) {
1858 ALOGD("Not updating touch focus because injection was denied.");
1859 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001860 }
1861
1862Unresponsive:
1863 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1864 mTempTouchState.reset();
1865
1866 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001867 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001868 if (DEBUG_FOCUS) {
1869 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1870 "timeSpentWaitingForApplication=%0.1fms",
1871 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1872 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001873 return injectionResult;
1874}
1875
1876void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001877 int32_t targetFlags, BitSet32 pointerIds,
1878 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00001879 std::vector<InputTarget>::iterator it =
1880 std::find_if(inputTargets.begin(), inputTargets.end(),
1881 [&windowHandle](const InputTarget& inputTarget) {
1882 return inputTarget.inputChannel->getConnectionToken() ==
1883 windowHandle->getToken();
1884 });
chaviw5d22a232019-12-11 16:47:32 -08001885
Chavi Weingartenb38d8c62020-01-08 21:20:39 +00001886 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00001887
1888 if (it == inputTargets.end()) {
1889 InputTarget inputTarget;
1890 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1891 if (inputChannel == nullptr) {
1892 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1893 return;
1894 }
1895 inputTarget.inputChannel = inputChannel;
1896 inputTarget.flags = targetFlags;
1897 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
1898 inputTargets.push_back(inputTarget);
1899 it = inputTargets.end() - 1;
1900 }
1901
1902 ALOG_ASSERT(it->flags == targetFlags);
1903 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
1904
1905 it->addPointers(pointerIds, -windowInfo->frameLeft, -windowInfo->frameTop,
1906 windowInfo->windowXScale, windowInfo->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001907}
1908
Michael Wright3dd60e22019-03-27 22:06:44 +00001909void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001910 int32_t displayId, float xOffset,
1911 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001912 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1913 mGlobalMonitorsByDisplay.find(displayId);
1914
1915 if (it != mGlobalMonitorsByDisplay.end()) {
1916 const std::vector<Monitor>& monitors = it->second;
1917 for (const Monitor& monitor : monitors) {
1918 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001919 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920 }
1921}
1922
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001923void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
1924 float yOffset,
1925 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001926 InputTarget target;
1927 target.inputChannel = monitor.inputChannel;
1928 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00001929 target.setDefaultPointerInfo(xOffset, yOffset, 1 /* windowXScale */, 1 /* windowYScale */);
Michael Wright3dd60e22019-03-27 22:06:44 +00001930 inputTargets.push_back(target);
1931}
1932
Michael Wrightd02c5b62014-02-10 15:10:22 -08001933bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001934 const InjectionState* injectionState) {
1935 if (injectionState &&
1936 (windowHandle == nullptr ||
1937 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
1938 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001939 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001940 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001941 "owned by uid %d",
1942 injectionState->injectorPid, injectionState->injectorUid,
1943 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001944 } else {
1945 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001946 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001947 }
1948 return false;
1949 }
1950 return true;
1951}
1952
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001953bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
1954 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001955 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001956 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1957 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001958 if (otherHandle == windowHandle) {
1959 break;
1960 }
1961
1962 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001963 if (otherInfo->displayId == displayId && otherInfo->visible &&
1964 !otherInfo->isTrustedOverlay() && otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001965 return true;
1966 }
1967 }
1968 return false;
1969}
1970
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001971bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1972 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001973 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001974 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001975 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001976 if (otherHandle == windowHandle) {
1977 break;
1978 }
1979
1980 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001981 if (otherInfo->displayId == displayId && otherInfo->visible &&
1982 !otherInfo->isTrustedOverlay() && otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001983 return true;
1984 }
1985 }
1986 return false;
1987}
1988
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001989std::string InputDispatcher::checkWindowReadyForMoreInputLocked(
1990 nsecs_t currentTime, const sp<InputWindowHandle>& windowHandle,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001991 const EventEntry& eventEntry, const char* targetType) {
Jeff Brownffb49772014-10-10 19:01:34 -07001992 // If the window is paused then keep waiting.
1993 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001994 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001995 }
1996
1997 // If the window's connection is not registered then keep waiting.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001998 sp<Connection> connection = getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001999 if (connection == nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002000 return StringPrintf("Waiting because the %s window's input channel is not "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002001 "registered with the input dispatcher. The window may be in the "
2002 "process of being removed.",
2003 targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07002004 }
2005
2006 // If the connection is dead then keep waiting.
Jeff Brownffb49772014-10-10 19:01:34 -07002007 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002008 return StringPrintf("Waiting because the %s window's input connection is %s."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002009 "The window may be in the process of being removed.",
2010 targetType, connection->getStatusLabel());
Jeff Brownffb49772014-10-10 19:01:34 -07002011 }
2012
2013 // If the connection is backed up then keep waiting.
2014 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002015 return StringPrintf("Waiting because the %s window's input channel is full. "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002016 "Outbound queue length: %zu. Wait queue length: %zu.",
2017 targetType, connection->outboundQueue.size(),
2018 connection->waitQueue.size());
Jeff Brownffb49772014-10-10 19:01:34 -07002019 }
2020
2021 // Ensure that the dispatch queues aren't too far backed up for this event.
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002022 if (eventEntry.type == EventEntry::Type::KEY) {
Jeff Brownffb49772014-10-10 19:01:34 -07002023 // If the event is a key event, then we must wait for all previous events to
2024 // complete before delivering it because previous events may have the
2025 // side-effect of transferring focus to a different window and we want to
2026 // ensure that the following keys are sent to the new window.
2027 //
2028 // Suppose the user touches a button in a window then immediately presses "A".
2029 // If the button causes a pop-up window to appear then we want to ensure that
2030 // the "A" key is delivered to the new pop-up window. This is because users
2031 // often anticipate pending UI changes when typing on a keyboard.
2032 // To obtain this behavior, we must serialize key events with respect to all
2033 // prior input events.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002034 if (!connection->outboundQueue.empty() || !connection->waitQueue.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002035 return StringPrintf("Waiting to send key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002036 "finished processing all of the input events that were previously "
2037 "delivered to it. Outbound queue length: %zu. Wait queue length: "
2038 "%zu.",
2039 targetType, connection->outboundQueue.size(),
2040 connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002041 }
Jeff Brownffb49772014-10-10 19:01:34 -07002042 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002043 // Touch events can always be sent to a window immediately because the user intended
2044 // to touch whatever was visible at the time. Even if focus changes or a new
2045 // window appears moments later, the touch event was meant to be delivered to
2046 // whatever window happened to be on screen at the time.
2047 //
2048 // Generic motion events, such as trackball or joystick events are a little trickier.
2049 // Like key events, generic motion events are delivered to the focused window.
2050 // Unlike key events, generic motion events don't tend to transfer focus to other
2051 // windows and it is not important for them to be serialized. So we prefer to deliver
2052 // generic motion events as soon as possible to improve efficiency and reduce lag
2053 // through batching.
2054 //
2055 // The one case where we pause input event delivery is when the wait queue is piling
2056 // up with lots of events because the application is not responding.
2057 // This condition ensures that ANRs are detected reliably.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002058 if (!connection->waitQueue.empty() &&
2059 currentTime >=
2060 connection->waitQueue.front()->deliveryTime + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002061 return StringPrintf("Waiting to send non-key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002062 "finished processing certain input events that were delivered to "
2063 "it over "
2064 "%0.1fms ago. Wait queue length: %zu. Wait queue head age: "
2065 "%0.1fms.",
2066 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
2067 connection->waitQueue.size(),
2068 (currentTime - connection->waitQueue.front()->deliveryTime) *
2069 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002070 }
2071 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002072 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002073}
2074
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002075std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002076 const sp<InputApplicationHandle>& applicationHandle,
2077 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002078 if (applicationHandle != nullptr) {
2079 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002080 std::string label(applicationHandle->getName());
2081 label += " - ";
2082 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002083 return label;
2084 } else {
2085 return applicationHandle->getName();
2086 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002087 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002088 return windowHandle->getName();
2089 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002090 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002091 }
2092}
2093
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002094void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002095 if (eventEntry.type == EventEntry::Type::FOCUS) {
2096 // Focus events are passed to apps, but do not represent user activity.
2097 return;
2098 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002099 int32_t displayId = getTargetDisplayId(eventEntry);
2100 sp<InputWindowHandle> focusedWindowHandle =
2101 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
2102 if (focusedWindowHandle != nullptr) {
2103 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002104 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
2105#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002106 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002107#endif
2108 return;
2109 }
2110 }
2111
2112 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002113 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002114 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002115 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2116 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002117 return;
2118 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002119
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002120 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002121 eventType = USER_ACTIVITY_EVENT_TOUCH;
2122 }
2123 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002124 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002125 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002126 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2127 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002128 return;
2129 }
2130 eventType = USER_ACTIVITY_EVENT_BUTTON;
2131 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002132 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002133 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002134 case EventEntry::Type::CONFIGURATION_CHANGED:
2135 case EventEntry::Type::DEVICE_RESET: {
2136 LOG_ALWAYS_FATAL("%s events are not user activity",
2137 EventEntry::typeToString(eventEntry.type));
2138 break;
2139 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002140 }
2141
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002142 std::unique_ptr<CommandEntry> commandEntry =
2143 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002144 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002145 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002146 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002147}
2148
2149void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002150 const sp<Connection>& connection,
2151 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002152 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002153 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002154 std::string message =
2155 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2156 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002157 ATRACE_NAME(message.c_str());
2158 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002159#if DEBUG_DISPATCH_CYCLE
2160 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002161 "globalScaleFactor=%f, pointerIds=0x%x %s",
2162 connection->getInputChannelName().c_str(), inputTarget.flags,
2163 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2164 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002165#endif
2166
2167 // Skip this event if the connection status is not normal.
2168 // We don't want to enqueue additional outbound events if the connection is broken.
2169 if (connection->status != Connection::STATUS_NORMAL) {
2170#if DEBUG_DISPATCH_CYCLE
2171 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002172 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002173#endif
2174 return;
2175 }
2176
2177 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002178 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2179 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2180 "Entry type %s should not have FLAG_SPLIT",
2181 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002182
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002183 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002184 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002185 MotionEntry* splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002186 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002187 if (!splitMotionEntry) {
2188 return; // split event was dropped
2189 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002190 if (DEBUG_FOCUS) {
2191 ALOGD("channel '%s' ~ Split motion event.",
2192 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002193 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002194 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002195 enqueueDispatchEntriesLocked(currentTime, connection, splitMotionEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002196 splitMotionEntry->release();
2197 return;
2198 }
2199 }
2200
2201 // Not splitting. Enqueue dispatch entries for the event as is.
2202 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2203}
2204
2205void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002206 const sp<Connection>& connection,
2207 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002208 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002209 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002210 std::string message =
2211 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32
2212 ")",
2213 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002214 ATRACE_NAME(message.c_str());
2215 }
2216
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002217 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002218
2219 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002220 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002221 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002222 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002223 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002224 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002225 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002226 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002227 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002228 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002229 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002230 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002231 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002232
2233 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002234 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002235 startDispatchCycleLocked(currentTime, connection);
2236 }
2237}
2238
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002239void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
2240 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002241 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002242 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002243 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002244 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2245 connection->getInputChannelName().c_str(),
2246 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002247 ATRACE_NAME(message.c_str());
2248 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002249 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002250 if (!(inputTargetFlags & dispatchMode)) {
2251 return;
2252 }
2253 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2254
2255 // This is a new event.
2256 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002257 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002258 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002259
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002260 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2261 // different EventEntry than what was passed in.
2262 EventEntry* newEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002263 // Apply target flags and update the connection's input state.
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002264 switch (newEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002265 case EventEntry::Type::KEY: {
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002266 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*newEntry);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002267 dispatchEntry->resolvedAction = keyEntry.action;
2268 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002269
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002270 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2271 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002272#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002273 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2274 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002275#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002276 return; // skip the inconsistent event
2277 }
2278 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002279 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002280
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002281 case EventEntry::Type::MOTION: {
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002282 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*newEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002283 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2284 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2285 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2286 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2287 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2288 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2289 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2290 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2291 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2292 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2293 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002294 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002295 }
2296 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002297 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2298 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002299#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002300 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2301 "event",
2302 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002303#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002304 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2305 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002306
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002307 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002308 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2309 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2310 }
2311 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2312 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2313 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002314
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002315 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2316 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002317#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002318 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2319 "event",
2320 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002321#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002322 return; // skip the inconsistent event
2323 }
2324
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002325 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002326 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002327
2328 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002329 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002330 case EventEntry::Type::FOCUS: {
2331 break;
2332 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002333 case EventEntry::Type::CONFIGURATION_CHANGED:
2334 case EventEntry::Type::DEVICE_RESET: {
2335 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002336 EventEntry::typeToString(newEntry->type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002337 break;
2338 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002339 }
2340
2341 // Remember that we are waiting for this dispatch to complete.
2342 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002343 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002344 }
2345
2346 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002347 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002348 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002349}
2350
chaviwfd6d3512019-03-25 13:23:49 -07002351void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002352 const sp<IBinder>& newToken) {
chaviw8c9cf542019-03-25 13:02:48 -07002353 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002354 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2355 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002356 return;
2357 }
2358
2359 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2360 if (inputWindowHandle == nullptr) {
2361 return;
2362 }
2363
chaviw8c9cf542019-03-25 13:02:48 -07002364 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002365 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002366
2367 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2368
2369 if (!hasFocusChanged) {
2370 return;
2371 }
2372
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002373 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2374 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002375 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002376 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002377}
2378
2379void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002380 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002381 if (ATRACE_ENABLED()) {
2382 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002383 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002384 ATRACE_NAME(message.c_str());
2385 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002386#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002387 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002388#endif
2389
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002390 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2391 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002392 dispatchEntry->deliveryTime = currentTime;
2393
2394 // Publish the event.
2395 status_t status;
2396 EventEntry* eventEntry = dispatchEntry->eventEntry;
2397 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002398 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002399 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002400
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002401 // Publish the key event.
2402 status = connection->inputPublisher
2403 .publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId,
2404 keyEntry->source, keyEntry->displayId,
2405 dispatchEntry->resolvedAction,
2406 dispatchEntry->resolvedFlags, keyEntry->keyCode,
2407 keyEntry->scanCode, keyEntry->metaState,
2408 keyEntry->repeatCount, keyEntry->downTime,
2409 keyEntry->eventTime);
2410 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002411 }
2412
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002413 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002414 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002415
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002416 PointerCoords scaledCoords[MAX_POINTERS];
2417 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2418
2419 // Set the X and Y offset depending on the input source.
2420 float xOffset, yOffset;
2421 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
2422 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2423 float globalScaleFactor = dispatchEntry->globalScaleFactor;
2424 float wxs = dispatchEntry->windowXScale;
2425 float wys = dispatchEntry->windowYScale;
2426 xOffset = dispatchEntry->xOffset * wxs;
2427 yOffset = dispatchEntry->yOffset * wys;
2428 if (wxs != 1.0f || wys != 1.0f || globalScaleFactor != 1.0f) {
2429 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2430 scaledCoords[i] = motionEntry->pointerCoords[i];
2431 scaledCoords[i].scale(globalScaleFactor, wxs, wys);
2432 }
2433 usingCoords = scaledCoords;
2434 }
2435 } else {
2436 xOffset = 0.0f;
2437 yOffset = 0.0f;
2438
2439 // We don't want the dispatch target to know.
2440 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
2441 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2442 scaledCoords[i].clear();
2443 }
2444 usingCoords = scaledCoords;
2445 }
2446 }
2447
2448 // Publish the motion event.
2449 status = connection->inputPublisher
2450 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2451 motionEntry->source, motionEntry->displayId,
2452 dispatchEntry->resolvedAction,
2453 motionEntry->actionButton,
2454 dispatchEntry->resolvedFlags,
2455 motionEntry->edgeFlags, motionEntry->metaState,
2456 motionEntry->buttonState,
2457 motionEntry->classification, xOffset, yOffset,
2458 motionEntry->xPrecision,
2459 motionEntry->yPrecision,
2460 motionEntry->xCursorPosition,
2461 motionEntry->yCursorPosition,
2462 motionEntry->downTime, motionEntry->eventTime,
2463 motionEntry->pointerCount,
2464 motionEntry->pointerProperties, usingCoords);
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05002465 reportTouchEventForStatistics(*motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002466 break;
2467 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002468 case EventEntry::Type::FOCUS: {
2469 FocusEntry* focusEntry = static_cast<FocusEntry*>(eventEntry);
2470 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
2471 focusEntry->hasFocus,
2472 mInTouchMode);
2473 break;
2474 }
2475
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002476 case EventEntry::Type::CONFIGURATION_CHANGED:
2477 case EventEntry::Type::DEVICE_RESET: {
2478 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
2479 EventEntry::typeToString(eventEntry->type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002480 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002481 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002482 }
2483
2484 // Check the result.
2485 if (status) {
2486 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002487 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002488 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002489 "This is unexpected because the wait queue is empty, so the pipe "
2490 "should be empty and we shouldn't have any problems writing an "
2491 "event to it, status=%d",
2492 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002493 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2494 } else {
2495 // Pipe is full and we are waiting for the app to finish process some events
2496 // before sending more events to it.
2497#if DEBUG_DISPATCH_CYCLE
2498 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002499 "waiting for the application to catch up",
2500 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002501#endif
2502 connection->inputPublisherBlocked = true;
2503 }
2504 } else {
2505 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002506 "status=%d",
2507 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002508 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2509 }
2510 return;
2511 }
2512
2513 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002514 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2515 connection->outboundQueue.end(),
2516 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002517 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002518 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002519 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002520 }
2521}
2522
2523void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002524 const sp<Connection>& connection, uint32_t seq,
2525 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002526#if DEBUG_DISPATCH_CYCLE
2527 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002528 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002529#endif
2530
2531 connection->inputPublisherBlocked = false;
2532
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002533 if (connection->status == Connection::STATUS_BROKEN ||
2534 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002535 return;
2536 }
2537
2538 // Notify other system components and prepare to start the next dispatch cycle.
2539 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2540}
2541
2542void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002543 const sp<Connection>& connection,
2544 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002545#if DEBUG_DISPATCH_CYCLE
2546 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002547 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002548#endif
2549
2550 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002551 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002552 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002553 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002554 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002555
2556 // The connection appears to be unrecoverably broken.
2557 // Ignore already broken or zombie connections.
2558 if (connection->status == Connection::STATUS_NORMAL) {
2559 connection->status = Connection::STATUS_BROKEN;
2560
2561 if (notify) {
2562 // Notify other system components.
2563 onDispatchCycleBrokenLocked(currentTime, connection);
2564 }
2565 }
2566}
2567
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002568void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2569 while (!queue.empty()) {
2570 DispatchEntry* dispatchEntry = queue.front();
2571 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002572 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002573 }
2574}
2575
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002576void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002577 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002578 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002579 }
2580 delete dispatchEntry;
2581}
2582
2583int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2584 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2585
2586 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002587 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002588
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002589 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002590 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002591 "fd=%d, events=0x%x",
2592 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002593 return 0; // remove the callback
2594 }
2595
2596 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002597 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002598 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2599 if (!(events & ALOOPER_EVENT_INPUT)) {
2600 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002601 "events=0x%x",
2602 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002603 return 1;
2604 }
2605
2606 nsecs_t currentTime = now();
2607 bool gotOne = false;
2608 status_t status;
2609 for (;;) {
2610 uint32_t seq;
2611 bool handled;
2612 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2613 if (status) {
2614 break;
2615 }
2616 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2617 gotOne = true;
2618 }
2619 if (gotOne) {
2620 d->runCommandsLockedInterruptible();
2621 if (status == WOULD_BLOCK) {
2622 return 1;
2623 }
2624 }
2625
2626 notify = status != DEAD_OBJECT || !connection->monitor;
2627 if (notify) {
2628 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002629 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002630 }
2631 } else {
2632 // Monitor channels are never explicitly unregistered.
2633 // We do it automatically when the remote endpoint is closed so don't warn
2634 // about them.
2635 notify = !connection->monitor;
2636 if (notify) {
2637 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002638 "events=0x%x",
2639 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002640 }
2641 }
2642
2643 // Unregister the channel.
2644 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2645 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002646 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08002647}
2648
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002649void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002650 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002651 for (const auto& pair : mConnectionsByFd) {
2652 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002653 }
2654}
2655
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002656void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002657 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002658 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2659 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2660}
2661
2662void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2663 const CancelationOptions& options,
2664 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2665 for (const auto& it : monitorsByDisplay) {
2666 const std::vector<Monitor>& monitors = it.second;
2667 for (const Monitor& monitor : monitors) {
2668 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002669 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002670 }
2671}
2672
Michael Wrightd02c5b62014-02-10 15:10:22 -08002673void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2674 const sp<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002675 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002676 if (connection == nullptr) {
2677 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002678 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002679
2680 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002681}
2682
2683void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2684 const sp<Connection>& connection, const CancelationOptions& options) {
2685 if (connection->status == Connection::STATUS_BROKEN) {
2686 return;
2687 }
2688
2689 nsecs_t currentTime = now();
2690
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07002691 std::vector<EventEntry*> cancelationEvents =
2692 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002693
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002694 if (cancelationEvents.empty()) {
2695 return;
2696 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002697#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002698 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
2699 "with reality: %s, mode=%d.",
2700 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
2701 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002702#endif
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002703 for (size_t i = 0; i < cancelationEvents.size(); i++) {
2704 EventEntry* cancelationEventEntry = cancelationEvents[i];
2705 switch (cancelationEventEntry->type) {
2706 case EventEntry::Type::KEY: {
2707 logOutboundKeyDetails("cancel - ",
2708 static_cast<const KeyEntry&>(*cancelationEventEntry));
2709 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002710 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002711 case EventEntry::Type::MOTION: {
2712 logOutboundMotionDetails("cancel - ",
2713 static_cast<const MotionEntry&>(*cancelationEventEntry));
2714 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002715 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002716 case EventEntry::Type::FOCUS: {
2717 LOG_ALWAYS_FATAL("Canceling focus events is not supported");
2718 break;
2719 }
2720 case EventEntry::Type::CONFIGURATION_CHANGED:
2721 case EventEntry::Type::DEVICE_RESET: {
2722 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2723 EventEntry::typeToString(cancelationEventEntry->type));
2724 break;
2725 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002726 }
2727
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002728 InputTarget target;
2729 sp<InputWindowHandle> windowHandle =
2730 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
2731 if (windowHandle != nullptr) {
2732 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2733 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2734 windowInfo->windowXScale, windowInfo->windowYScale);
2735 target.globalScaleFactor = windowInfo->globalScaleFactor;
2736 }
2737 target.inputChannel = connection->inputChannel;
2738 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2739
2740 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
2741 target, InputTarget::FLAG_DISPATCH_AS_IS);
2742
2743 cancelationEventEntry->release();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002744 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002745
2746 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002747}
2748
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002749MotionEntry* InputDispatcher::splitMotionEvent(const MotionEntry& originalMotionEntry,
Garfield Tane84e6f92019-08-29 17:28:41 -07002750 BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002751 ALOG_ASSERT(pointerIds.value != 0);
2752
2753 uint32_t splitPointerIndexMap[MAX_POINTERS];
2754 PointerProperties splitPointerProperties[MAX_POINTERS];
2755 PointerCoords splitPointerCoords[MAX_POINTERS];
2756
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002757 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002758 uint32_t splitPointerCount = 0;
2759
2760 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002761 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002762 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002763 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002764 uint32_t pointerId = uint32_t(pointerProperties.id);
2765 if (pointerIds.hasBit(pointerId)) {
2766 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2767 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2768 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002769 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002770 splitPointerCount += 1;
2771 }
2772 }
2773
2774 if (splitPointerCount != pointerIds.count()) {
2775 // This is bad. We are missing some of the pointers that we expected to deliver.
2776 // Most likely this indicates that we received an ACTION_MOVE events that has
2777 // different pointer ids than we expected based on the previous ACTION_DOWN
2778 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2779 // in this way.
2780 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002781 "we expected there to be %d pointers. This probably means we received "
2782 "a broken sequence of pointer ids from the input device.",
2783 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002784 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002785 }
2786
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002787 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002788 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002789 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
2790 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002791 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2792 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002793 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002794 uint32_t pointerId = uint32_t(pointerProperties.id);
2795 if (pointerIds.hasBit(pointerId)) {
2796 if (pointerIds.count() == 1) {
2797 // The first/last pointer went down/up.
2798 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002799 ? AMOTION_EVENT_ACTION_DOWN
2800 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002801 } else {
2802 // A secondary pointer went down/up.
2803 uint32_t splitPointerIndex = 0;
2804 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2805 splitPointerIndex += 1;
2806 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002807 action = maskedAction |
2808 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002809 }
2810 } else {
2811 // An unrelated pointer changed.
2812 action = AMOTION_EVENT_ACTION_MOVE;
2813 }
2814 }
2815
Garfield Tan00f511d2019-06-12 16:55:40 -07002816 MotionEntry* splitMotionEntry =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002817 new MotionEntry(originalMotionEntry.sequenceNum, originalMotionEntry.eventTime,
2818 originalMotionEntry.deviceId, originalMotionEntry.source,
2819 originalMotionEntry.displayId, originalMotionEntry.policyFlags, action,
2820 originalMotionEntry.actionButton, originalMotionEntry.flags,
2821 originalMotionEntry.metaState, originalMotionEntry.buttonState,
2822 originalMotionEntry.classification, originalMotionEntry.edgeFlags,
2823 originalMotionEntry.xPrecision, originalMotionEntry.yPrecision,
2824 originalMotionEntry.xCursorPosition,
2825 originalMotionEntry.yCursorPosition, originalMotionEntry.downTime,
Garfield Tan00f511d2019-06-12 16:55:40 -07002826 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002827
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002828 if (originalMotionEntry.injectionState) {
2829 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002830 splitMotionEntry->injectionState->refCount += 1;
2831 }
2832
2833 return splitMotionEntry;
2834}
2835
2836void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2837#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002838 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002839#endif
2840
2841 bool needWake;
2842 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002843 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002844
Prabir Pradhan42611e02018-11-27 14:04:02 -08002845 ConfigurationChangedEntry* newEntry =
2846 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002847 needWake = enqueueInboundEventLocked(newEntry);
2848 } // release lock
2849
2850 if (needWake) {
2851 mLooper->wake();
2852 }
2853}
2854
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002855/**
2856 * If one of the meta shortcuts is detected, process them here:
2857 * Meta + Backspace -> generate BACK
2858 * Meta + Enter -> generate HOME
2859 * This will potentially overwrite keyCode and metaState.
2860 */
2861void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002862 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002863 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2864 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2865 if (keyCode == AKEYCODE_DEL) {
2866 newKeyCode = AKEYCODE_BACK;
2867 } else if (keyCode == AKEYCODE_ENTER) {
2868 newKeyCode = AKEYCODE_HOME;
2869 }
2870 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002871 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002872 struct KeyReplacement replacement = {keyCode, deviceId};
2873 mReplacedKeys.add(replacement, newKeyCode);
2874 keyCode = newKeyCode;
2875 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2876 }
2877 } else if (action == AKEY_EVENT_ACTION_UP) {
2878 // In order to maintain a consistent stream of up and down events, check to see if the key
2879 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2880 // even if the modifier was released between the down and the up events.
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 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2884 if (index >= 0) {
2885 keyCode = mReplacedKeys.valueAt(index);
2886 mReplacedKeys.removeItemsAt(index);
2887 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2888 }
2889 }
2890}
2891
Michael Wrightd02c5b62014-02-10 15:10:22 -08002892void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2893#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002894 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
2895 "policyFlags=0x%x, action=0x%x, "
2896 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
2897 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2898 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
2899 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002900#endif
2901 if (!validateKeyEvent(args->action)) {
2902 return;
2903 }
2904
2905 uint32_t policyFlags = args->policyFlags;
2906 int32_t flags = args->flags;
2907 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002908 // InputDispatcher tracks and generates key repeats on behalf of
2909 // whatever notifies it, so repeatCount should always be set to 0
2910 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002911 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2912 policyFlags |= POLICY_FLAG_VIRTUAL;
2913 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2914 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002915 if (policyFlags & POLICY_FLAG_FUNCTION) {
2916 metaState |= AMETA_FUNCTION_ON;
2917 }
2918
2919 policyFlags |= POLICY_FLAG_TRUSTED;
2920
Michael Wright78f24442014-08-06 15:55:28 -07002921 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002922 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002923
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924 KeyEvent event;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002925 event.initialize(args->deviceId, args->source, args->displayId, args->action, flags, keyCode,
2926 args->scanCode, metaState, repeatCount, args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002927
Michael Wright2b3c3302018-03-02 17:19:13 +00002928 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002929 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002930 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2931 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002932 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00002933 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002934
Michael Wrightd02c5b62014-02-10 15:10:22 -08002935 bool needWake;
2936 { // acquire lock
2937 mLock.lock();
2938
2939 if (shouldSendKeyToInputFilterLocked(args)) {
2940 mLock.unlock();
2941
2942 policyFlags |= POLICY_FLAG_FILTERED;
2943 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2944 return; // event was consumed by the filter
2945 }
2946
2947 mLock.lock();
2948 }
2949
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002950 KeyEntry* newEntry =
2951 new KeyEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2952 args->displayId, policyFlags, args->action, flags, keyCode,
2953 args->scanCode, metaState, repeatCount, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002954
2955 needWake = enqueueInboundEventLocked(newEntry);
2956 mLock.unlock();
2957 } // release lock
2958
2959 if (needWake) {
2960 mLooper->wake();
2961 }
2962}
2963
2964bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2965 return mInputFilterEnabled;
2966}
2967
2968void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2969#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002970 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07002971 ", policyFlags=0x%x, "
2972 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
2973 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07002974 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07002975 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2976 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
Jaewan Kim372fbe42019-10-02 10:58:46 +09002977 args->edgeFlags, args->xPrecision, args->yPrecision, args->xCursorPosition,
Garfield Tan00f511d2019-06-12 16:55:40 -07002978 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002979 for (uint32_t i = 0; i < args->pointerCount; i++) {
2980 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002981 "x=%f, y=%f, pressure=%f, size=%f, "
2982 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2983 "orientation=%f",
2984 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
2985 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2986 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2987 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2988 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2989 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2990 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2991 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2992 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2993 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002994 }
2995#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002996 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
2997 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002998 return;
2999 }
3000
3001 uint32_t policyFlags = args->policyFlags;
3002 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003003
3004 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003005 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003006 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3007 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003008 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003009 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003010
3011 bool needWake;
3012 { // acquire lock
3013 mLock.lock();
3014
3015 if (shouldSendMotionToInputFilterLocked(args)) {
3016 mLock.unlock();
3017
3018 MotionEvent event;
Garfield Tan00f511d2019-06-12 16:55:40 -07003019 event.initialize(args->deviceId, args->source, args->displayId, args->action,
3020 args->actionButton, args->flags, args->edgeFlags, args->metaState,
3021 args->buttonState, args->classification, 0, 0, args->xPrecision,
3022 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3023 args->downTime, args->eventTime, args->pointerCount,
3024 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003025
3026 policyFlags |= POLICY_FLAG_FILTERED;
3027 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3028 return; // event was consumed by the filter
3029 }
3030
3031 mLock.lock();
3032 }
3033
3034 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07003035 MotionEntry* newEntry =
3036 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
3037 args->displayId, policyFlags, args->action, args->actionButton,
3038 args->flags, args->metaState, args->buttonState,
3039 args->classification, args->edgeFlags, args->xPrecision,
3040 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3041 args->downTime, args->pointerCount, args->pointerProperties,
3042 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003043
3044 needWake = enqueueInboundEventLocked(newEntry);
3045 mLock.unlock();
3046 } // release lock
3047
3048 if (needWake) {
3049 mLooper->wake();
3050 }
3051}
3052
3053bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003054 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003055}
3056
3057void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3058#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003059 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003060 "switchMask=0x%08x",
3061 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003062#endif
3063
3064 uint32_t policyFlags = args->policyFlags;
3065 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003066 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003067}
3068
3069void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3070#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003071 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3072 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003073#endif
3074
3075 bool needWake;
3076 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003077 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003078
Prabir Pradhan42611e02018-11-27 14:04:02 -08003079 DeviceResetEntry* newEntry =
3080 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003081 needWake = enqueueInboundEventLocked(newEntry);
3082 } // release lock
3083
3084 if (needWake) {
3085 mLooper->wake();
3086 }
3087}
3088
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003089int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid,
3090 int32_t injectorUid, int32_t syncMode,
3091 int32_t timeoutMillis, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003092#if DEBUG_INBOUND_EVENT_DETAILS
3093 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003094 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
3095 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003096#endif
3097
3098 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
3099
3100 policyFlags |= POLICY_FLAG_INJECTED;
3101 if (hasInjectionPermission(injectorPid, injectorUid)) {
3102 policyFlags |= POLICY_FLAG_TRUSTED;
3103 }
3104
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003105 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003106 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003107 case AINPUT_EVENT_TYPE_KEY: {
3108 KeyEvent keyEvent;
3109 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
3110 int32_t action = keyEvent.getAction();
3111 if (!validateKeyEvent(action)) {
3112 return INPUT_EVENT_INJECTION_FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003113 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003114
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003115 int32_t flags = keyEvent.getFlags();
3116 int32_t keyCode = keyEvent.getKeyCode();
3117 int32_t metaState = keyEvent.getMetaState();
3118 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
3119 /*byref*/ keyCode, /*byref*/ metaState);
3120 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(),
3121 keyEvent.getDisplayId(), action, flags, keyCode,
3122 keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
3123 keyEvent.getDownTime(), keyEvent.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003124
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003125 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3126 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003127 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003128
3129 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3130 android::base::Timer t;
3131 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3132 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3133 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3134 std::to_string(t.duration().count()).c_str());
3135 }
3136 }
3137
3138 mLock.lock();
3139 KeyEntry* injectedEntry =
3140 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
3141 keyEvent.getDeviceId(), keyEvent.getSource(),
3142 keyEvent.getDisplayId(), policyFlags, action, flags,
3143 keyEvent.getKeyCode(), keyEvent.getScanCode(),
3144 keyEvent.getMetaState(), keyEvent.getRepeatCount(),
3145 keyEvent.getDownTime());
3146 injectedEntries.push(injectedEntry);
3147 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003148 }
3149
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003150 case AINPUT_EVENT_TYPE_MOTION: {
3151 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3152 int32_t action = motionEvent->getAction();
3153 size_t pointerCount = motionEvent->getPointerCount();
3154 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3155 int32_t actionButton = motionEvent->getActionButton();
3156 int32_t displayId = motionEvent->getDisplayId();
3157 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
3158 return INPUT_EVENT_INJECTION_FAILED;
3159 }
3160
3161 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3162 nsecs_t eventTime = motionEvent->getEventTime();
3163 android::base::Timer t;
3164 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3165 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3166 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3167 std::to_string(t.duration().count()).c_str());
3168 }
3169 }
3170
3171 mLock.lock();
3172 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3173 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
3174 MotionEntry* injectedEntry =
Garfield Tan00f511d2019-06-12 16:55:40 -07003175 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3176 motionEvent->getDeviceId(), motionEvent->getSource(),
3177 motionEvent->getDisplayId(), policyFlags, action, actionButton,
3178 motionEvent->getFlags(), motionEvent->getMetaState(),
3179 motionEvent->getButtonState(), motionEvent->getClassification(),
3180 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3181 motionEvent->getYPrecision(),
3182 motionEvent->getRawXCursorPosition(),
3183 motionEvent->getRawYCursorPosition(),
3184 motionEvent->getDownTime(), uint32_t(pointerCount),
3185 pointerProperties, samplePointerCoords,
3186 motionEvent->getXOffset(), motionEvent->getYOffset());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003187 injectedEntries.push(injectedEntry);
3188 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3189 sampleEventTimes += 1;
3190 samplePointerCoords += pointerCount;
3191 MotionEntry* nextInjectedEntry =
3192 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3193 motionEvent->getDeviceId(), motionEvent->getSource(),
3194 motionEvent->getDisplayId(), policyFlags, action,
3195 actionButton, motionEvent->getFlags(),
3196 motionEvent->getMetaState(), motionEvent->getButtonState(),
3197 motionEvent->getClassification(),
3198 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3199 motionEvent->getYPrecision(),
3200 motionEvent->getRawXCursorPosition(),
3201 motionEvent->getRawYCursorPosition(),
3202 motionEvent->getDownTime(), uint32_t(pointerCount),
3203 pointerProperties, samplePointerCoords,
3204 motionEvent->getXOffset(), motionEvent->getYOffset());
3205 injectedEntries.push(nextInjectedEntry);
3206 }
3207 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003208 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003209
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003210 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003211 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003212 return INPUT_EVENT_INJECTION_FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003213 }
3214
3215 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3216 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3217 injectionState->injectionIsAsync = true;
3218 }
3219
3220 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003221 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003222
3223 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003224 while (!injectedEntries.empty()) {
3225 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3226 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003227 }
3228
3229 mLock.unlock();
3230
3231 if (needWake) {
3232 mLooper->wake();
3233 }
3234
3235 int32_t injectionResult;
3236 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003237 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003238
3239 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3240 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3241 } else {
3242 for (;;) {
3243 injectionResult = injectionState->injectionResult;
3244 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3245 break;
3246 }
3247
3248 nsecs_t remainingTimeout = endTime - now();
3249 if (remainingTimeout <= 0) {
3250#if DEBUG_INJECTION
3251 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003252 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003253#endif
3254 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3255 break;
3256 }
3257
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003258 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003259 }
3260
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003261 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED &&
3262 syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003263 while (injectionState->pendingForegroundDispatches != 0) {
3264#if DEBUG_INJECTION
3265 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003266 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003267#endif
3268 nsecs_t remainingTimeout = endTime - now();
3269 if (remainingTimeout <= 0) {
3270#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003271 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3272 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003273#endif
3274 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3275 break;
3276 }
3277
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003278 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003279 }
3280 }
3281 }
3282
3283 injectionState->release();
3284 } // release lock
3285
3286#if DEBUG_INJECTION
3287 ALOGD("injectInputEvent - Finished with result %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003288 "injectorPid=%d, injectorUid=%d",
3289 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003290#endif
3291
3292 return injectionResult;
3293}
3294
3295bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003296 return injectorUid == 0 ||
3297 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003298}
3299
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003300void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003301 InjectionState* injectionState = entry->injectionState;
3302 if (injectionState) {
3303#if DEBUG_INJECTION
3304 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003305 "injectorPid=%d, injectorUid=%d",
3306 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003307#endif
3308
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003309 if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003310 // Log the outcome since the injector did not wait for the injection result.
3311 switch (injectionResult) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003312 case INPUT_EVENT_INJECTION_SUCCEEDED:
3313 ALOGV("Asynchronous input event injection succeeded.");
3314 break;
3315 case INPUT_EVENT_INJECTION_FAILED:
3316 ALOGW("Asynchronous input event injection failed.");
3317 break;
3318 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3319 ALOGW("Asynchronous input event injection permission denied.");
3320 break;
3321 case INPUT_EVENT_INJECTION_TIMED_OUT:
3322 ALOGW("Asynchronous input event injection timed out.");
3323 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003324 }
3325 }
3326
3327 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003328 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003329 }
3330}
3331
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003332void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003333 InjectionState* injectionState = entry->injectionState;
3334 if (injectionState) {
3335 injectionState->pendingForegroundDispatches += 1;
3336 }
3337}
3338
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003339void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003340 InjectionState* injectionState = entry->injectionState;
3341 if (injectionState) {
3342 injectionState->pendingForegroundDispatches -= 1;
3343
3344 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003345 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003346 }
3347 }
3348}
3349
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003350std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3351 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003352 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003353}
3354
Michael Wrightd02c5b62014-02-10 15:10:22 -08003355sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003356 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003357 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003358 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3359 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003360 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003361 return windowHandle;
3362 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003363 }
3364 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003365 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003366}
3367
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003368bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) 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>& handle : windowHandles) {
3372 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003373 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003374 ALOGE("Found window %s in display %" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003375 ", but it should belong to display %" PRId32,
3376 windowHandle->getName().c_str(), it.first,
3377 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003378 }
3379 return true;
3380 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003381 }
3382 }
3383 return false;
3384}
3385
Robert Carr5c8a0262018-10-03 16:30:44 -07003386sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3387 size_t count = mInputChannelsByToken.count(token);
3388 if (count == 0) {
3389 return nullptr;
3390 }
3391 return mInputChannelsByToken.at(token);
3392}
3393
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003394void InputDispatcher::updateWindowHandlesForDisplayLocked(
3395 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3396 if (inputWindowHandles.empty()) {
3397 // Remove all handles on a display if there are no windows left.
3398 mWindowHandlesByDisplay.erase(displayId);
3399 return;
3400 }
3401
3402 // Since we compare the pointer of input window handles across window updates, we need
3403 // to make sure the handle object for the same window stays unchanged across updates.
3404 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003405 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003406 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003407 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003408 }
3409
3410 std::vector<sp<InputWindowHandle>> newHandles;
3411 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3412 if (!handle->updateInfo()) {
3413 // handle no longer valid
3414 continue;
3415 }
3416
3417 const InputWindowInfo* info = handle->getInfo();
3418 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3419 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3420 const bool noInputChannel =
3421 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3422 const bool canReceiveInput =
3423 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3424 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3425 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003426 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003427 handle->getName().c_str());
3428 }
3429 continue;
3430 }
3431
3432 if (info->displayId != displayId) {
3433 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3434 handle->getName().c_str(), displayId, info->displayId);
3435 continue;
3436 }
3437
chaviwaf87b3e2019-10-01 16:59:28 -07003438 if (oldHandlesById.find(handle->getId()) != oldHandlesById.end()) {
3439 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003440 oldHandle->updateFrom(handle);
3441 newHandles.push_back(oldHandle);
3442 } else {
3443 newHandles.push_back(handle);
3444 }
3445 }
3446
3447 // Insert or replace
3448 mWindowHandlesByDisplay[displayId] = newHandles;
3449}
3450
Arthur Hungb92218b2018-08-14 12:00:21 +08003451/**
3452 * Called from InputManagerService, update window handle list by displayId that can receive input.
3453 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3454 * If set an empty list, remove all handles from the specific display.
3455 * For focused handle, check if need to change and send a cancel event to previous one.
3456 * For removed handle, check if need to send a cancel event if already in touch.
3457 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003458void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003459 int32_t displayId,
3460 const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003461 if (DEBUG_FOCUS) {
3462 std::string windowList;
3463 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
3464 windowList += iwh->getName() + " ";
3465 }
3466 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
3467 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003468 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003469 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003470
Arthur Hungb92218b2018-08-14 12:00:21 +08003471 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003472 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3473 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003474
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003475 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3476
Tiger Huang721e26f2018-07-24 22:26:19 +08003477 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003478 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003479 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3480 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3481 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3482 windowHandle->getInfo()->visible) {
3483 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003484 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003485 if (windowHandle == mLastHoverWindowHandle) {
3486 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003487 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003488 }
3489
3490 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003491 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003492 }
3493
Tiger Huang721e26f2018-07-24 22:26:19 +08003494 sp<InputWindowHandle> oldFocusedWindowHandle =
3495 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3496
chaviwaf87b3e2019-10-01 16:59:28 -07003497 if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003498 if (oldFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003499 if (DEBUG_FOCUS) {
3500 ALOGD("Focus left window: %s in display %" PRId32,
3501 oldFocusedWindowHandle->getName().c_str(), displayId);
3502 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003503 sp<InputChannel> focusedInputChannel =
3504 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003505 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003506 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003507 "focus left window");
3508 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003509 enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003510 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003511 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003512 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003513 if (newFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003514 if (DEBUG_FOCUS) {
3515 ALOGD("Focus entered window: %s in display %" PRId32,
3516 newFocusedWindowHandle->getName().c_str(), displayId);
3517 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003518 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003519 enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003520 }
Robert Carrf759f162018-11-13 12:57:11 -08003521
3522 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003523 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003524 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003525 }
3526
Arthur Hungb92218b2018-08-14 12:00:21 +08003527 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3528 if (stateIndex >= 0) {
3529 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003530 for (size_t i = 0; i < state.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003531 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003532 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003533 if (DEBUG_FOCUS) {
3534 ALOGD("Touched window was removed: %s in display %" PRId32,
3535 touchedWindow.windowHandle->getName().c_str(), displayId);
3536 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003537 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003538 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003539 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003540 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003541 "touched window was removed");
3542 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
3543 options);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003544 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003545 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003546 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003547 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003548 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003549 }
3550 }
3551
3552 // Release information for windows that are no longer present.
3553 // This ensures that unused input channels are released promptly.
3554 // Otherwise, they might stick around until the window handle is destroyed
3555 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003556 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003557 if (!hasWindowHandleLocked(oldWindowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003558 if (DEBUG_FOCUS) {
3559 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
3560 }
Arthur Hung3b413f22018-10-26 18:05:34 +08003561 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003562 }
3563 }
3564 } // release lock
3565
3566 // Wake up poll loop since it may need to make new input dispatching choices.
3567 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003568
3569 if (setInputWindowsListener) {
3570 setInputWindowsListener->onSetInputWindowsFinished();
3571 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003572}
3573
3574void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003575 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003576 if (DEBUG_FOCUS) {
3577 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
3578 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
3579 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003580 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003581 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003582
Tiger Huang721e26f2018-07-24 22:26:19 +08003583 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3584 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003585 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003586 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3587 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003588 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003589 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003590 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003591 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003592 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003593 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003594 oldFocusedApplicationHandle.clear();
3595 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003596 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003597 } // release lock
3598
3599 // Wake up poll loop since it may need to make new input dispatching choices.
3600 mLooper->wake();
3601}
3602
Tiger Huang721e26f2018-07-24 22:26:19 +08003603/**
3604 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3605 * the display not specified.
3606 *
3607 * We track any unreleased events for each window. If a window loses the ability to receive the
3608 * released event, we will send a cancel event to it. So when the focused display is changed, we
3609 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3610 * display. The display-specified events won't be affected.
3611 */
3612void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003613 if (DEBUG_FOCUS) {
3614 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3615 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003616 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003617 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003618
3619 if (mFocusedDisplayId != displayId) {
3620 sp<InputWindowHandle> oldFocusedWindowHandle =
3621 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3622 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003623 sp<InputChannel> inputChannel =
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003624 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003625 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003626 CancelationOptions
3627 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3628 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003629 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003630 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3631 }
3632 }
3633 mFocusedDisplayId = displayId;
3634
3635 // Sanity check
3636 sp<InputWindowHandle> newFocusedWindowHandle =
3637 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003638 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003639
Tiger Huang721e26f2018-07-24 22:26:19 +08003640 if (newFocusedWindowHandle == nullptr) {
3641 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3642 if (!mFocusedWindowHandlesByDisplay.empty()) {
3643 ALOGE("But another display has a focused window:");
3644 for (auto& it : mFocusedWindowHandlesByDisplay) {
3645 const int32_t displayId = it.first;
3646 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003647 ALOGE("Display #%" PRId32 " has focused window: '%s'\n", displayId,
3648 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003649 }
3650 }
3651 }
3652 }
3653
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003654 if (DEBUG_FOCUS) {
3655 logDispatchStateLocked();
3656 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003657 } // release lock
3658
3659 // Wake up poll loop since it may need to make new input dispatching choices.
3660 mLooper->wake();
3661}
3662
Michael Wrightd02c5b62014-02-10 15:10:22 -08003663void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003664 if (DEBUG_FOCUS) {
3665 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3666 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003667
3668 bool changed;
3669 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003670 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003671
3672 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3673 if (mDispatchFrozen && !frozen) {
3674 resetANRTimeoutsLocked();
3675 }
3676
3677 if (mDispatchEnabled && !enabled) {
3678 resetAndDropEverythingLocked("dispatcher is being disabled");
3679 }
3680
3681 mDispatchEnabled = enabled;
3682 mDispatchFrozen = frozen;
3683 changed = true;
3684 } else {
3685 changed = false;
3686 }
3687
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003688 if (DEBUG_FOCUS) {
3689 logDispatchStateLocked();
3690 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003691 } // release lock
3692
3693 if (changed) {
3694 // Wake up poll loop since it may need to make new input dispatching choices.
3695 mLooper->wake();
3696 }
3697}
3698
3699void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003700 if (DEBUG_FOCUS) {
3701 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3702 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003703
3704 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003705 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003706
3707 if (mInputFilterEnabled == enabled) {
3708 return;
3709 }
3710
3711 mInputFilterEnabled = enabled;
3712 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3713 } // release lock
3714
3715 // Wake up poll loop since there might be work to do to drop everything.
3716 mLooper->wake();
3717}
3718
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08003719void InputDispatcher::setInTouchMode(bool inTouchMode) {
3720 std::scoped_lock lock(mLock);
3721 mInTouchMode = inTouchMode;
3722}
3723
chaviwfbe5d9c2018-12-26 12:23:37 -08003724bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3725 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003726 if (DEBUG_FOCUS) {
3727 ALOGD("Trivial transfer to same window.");
3728 }
chaviwfbe5d9c2018-12-26 12:23:37 -08003729 return true;
3730 }
3731
Michael Wrightd02c5b62014-02-10 15:10:22 -08003732 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003733 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003734
chaviwfbe5d9c2018-12-26 12:23:37 -08003735 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3736 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003737 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003738 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003739 return false;
3740 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003741 if (DEBUG_FOCUS) {
3742 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3743 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3744 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003745 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003746 if (DEBUG_FOCUS) {
3747 ALOGD("Cannot transfer focus because windows are on different displays.");
3748 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003749 return false;
3750 }
3751
3752 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003753 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3754 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3755 for (size_t i = 0; i < state.windows.size(); i++) {
3756 const TouchedWindow& touchedWindow = state.windows[i];
3757 if (touchedWindow.windowHandle == fromWindowHandle) {
3758 int32_t oldTargetFlags = touchedWindow.targetFlags;
3759 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003760
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003761 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003762
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003763 int32_t newTargetFlags = oldTargetFlags &
3764 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
3765 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003766 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003767
Jeff Brownf086ddb2014-02-11 14:28:48 -08003768 found = true;
3769 goto Found;
3770 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003771 }
3772 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003773 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003774
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003775 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003776 if (DEBUG_FOCUS) {
3777 ALOGD("Focus transfer failed because from window did not have focus.");
3778 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003779 return false;
3780 }
3781
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07003782 sp<Connection> fromConnection = getConnectionLocked(fromToken);
3783 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003784 if (fromConnection != nullptr && toConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003785 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003786 CancelationOptions
3787 options(CancelationOptions::CANCEL_POINTER_EVENTS,
3788 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003789 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
3790 }
3791
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003792 if (DEBUG_FOCUS) {
3793 logDispatchStateLocked();
3794 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003795 } // release lock
3796
3797 // Wake up poll loop since it may need to make new input dispatching choices.
3798 mLooper->wake();
3799 return true;
3800}
3801
3802void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003803 if (DEBUG_FOCUS) {
3804 ALOGD("Resetting and dropping all events (%s).", reason);
3805 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003806
3807 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3808 synthesizeCancelationEventsForAllConnectionsLocked(options);
3809
3810 resetKeyRepeatLocked();
3811 releasePendingEventLocked();
3812 drainInboundQueueLocked();
3813 resetANRTimeoutsLocked();
3814
Jeff Brownf086ddb2014-02-11 14:28:48 -08003815 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003816 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003817 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003818}
3819
3820void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003821 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003822 dumpDispatchStateLocked(dump);
3823
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003824 std::istringstream stream(dump);
3825 std::string line;
3826
3827 while (std::getline(stream, line, '\n')) {
3828 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003829 }
3830}
3831
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003832void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003833 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3834 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3835 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003836 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003837
Tiger Huang721e26f2018-07-24 22:26:19 +08003838 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3839 dump += StringPrintf(INDENT "FocusedApplications:\n");
3840 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3841 const int32_t displayId = it.first;
3842 const sp<InputApplicationHandle>& applicationHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003843 dump += StringPrintf(INDENT2 "displayId=%" PRId32
3844 ", name='%s', dispatchingTimeout=%0.3fms\n",
3845 displayId, applicationHandle->getName().c_str(),
3846 applicationHandle->getDispatchingTimeout(
3847 DEFAULT_INPUT_DISPATCHING_TIMEOUT) /
3848 1000000.0);
Tiger Huang721e26f2018-07-24 22:26:19 +08003849 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003850 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003851 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003852 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003853
3854 if (!mFocusedWindowHandlesByDisplay.empty()) {
3855 dump += StringPrintf(INDENT "FocusedWindows:\n");
3856 for (auto& it : mFocusedWindowHandlesByDisplay) {
3857 const int32_t displayId = it.first;
3858 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003859 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
3860 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003861 }
3862 } else {
3863 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3864 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865
Jeff Brownf086ddb2014-02-11 14:28:48 -08003866 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003867 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003868 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3869 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003870 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003871 state.displayId, toString(state.down), toString(state.split),
3872 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003873 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003874 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003875 for (size_t i = 0; i < state.windows.size(); i++) {
3876 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003877 dump += StringPrintf(INDENT4
3878 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3879 i, touchedWindow.windowHandle->getName().c_str(),
3880 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003881 }
3882 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003883 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003884 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003885 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003886 dump += INDENT3 "Portal windows:\n";
3887 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003888 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003889 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
3890 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003891 }
3892 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003893 }
3894 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003895 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003896 }
3897
Arthur Hungb92218b2018-08-14 12:00:21 +08003898 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003899 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003900 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003901 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003902 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003903 dump += INDENT2 "Windows:\n";
3904 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003905 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003906 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003907
Arthur Hungb92218b2018-08-14 12:00:21 +08003908 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003909 "portalToDisplayId=%d, paused=%s, hasFocus=%s, "
chaviwcb923212019-12-30 14:05:11 -08003910 "hasWallpaper=%s, visible=%s, canReceiveKeys=%s, "
3911 "flags=0x%08x, type=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003912 "frame=[%d,%d][%d,%d], globalScale=%f, "
chaviwcb923212019-12-30 14:05:11 -08003913 "windowScale=(%f,%f), touchableRegion=",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003914 i, windowInfo->name.c_str(), windowInfo->displayId,
3915 windowInfo->portalToDisplayId,
3916 toString(windowInfo->paused),
3917 toString(windowInfo->hasFocus),
3918 toString(windowInfo->hasWallpaper),
3919 toString(windowInfo->visible),
3920 toString(windowInfo->canReceiveKeys),
3921 windowInfo->layoutParamsFlags,
chaviwcb923212019-12-30 14:05:11 -08003922 windowInfo->layoutParamsType, windowInfo->frameLeft,
3923 windowInfo->frameTop, windowInfo->frameRight,
3924 windowInfo->frameBottom, windowInfo->globalScaleFactor,
3925 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003926 dumpRegion(dump, windowInfo->touchableRegion);
3927 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3928 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003929 windowInfo->ownerPid, windowInfo->ownerUid,
3930 windowInfo->dispatchingTimeout / 1000000.0);
Arthur Hungb92218b2018-08-14 12:00:21 +08003931 }
3932 } else {
3933 dump += INDENT2 "Windows: <none>\n";
3934 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003935 }
3936 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003937 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003938 }
3939
Michael Wright3dd60e22019-03-27 22:06:44 +00003940 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003941 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003942 const std::vector<Monitor>& monitors = it.second;
3943 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3944 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003945 }
3946 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003947 const std::vector<Monitor>& monitors = it.second;
3948 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
3949 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003950 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003951 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00003952 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003953 }
3954
3955 nsecs_t currentTime = now();
3956
3957 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003958 if (!mRecentQueue.empty()) {
3959 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
3960 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003961 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003963 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003964 }
3965 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003966 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003967 }
3968
3969 // Dump event currently being dispatched.
3970 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003971 dump += INDENT "PendingEvent:\n";
3972 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003973 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003974 dump += StringPrintf(", age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003975 (currentTime - mPendingEvent->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003977 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003978 }
3979
3980 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003981 if (!mInboundQueue.empty()) {
3982 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
3983 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003984 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003985 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003986 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003987 }
3988 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003989 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003990 }
3991
Michael Wright78f24442014-08-06 15:55:28 -07003992 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003993 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07003994 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
3995 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
3996 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003997 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n", i,
3998 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07003999 }
4000 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004001 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004002 }
4003
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004004 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004005 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004006 for (const auto& pair : mConnectionsByFd) {
4007 const sp<Connection>& connection = pair.second;
4008 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
4009 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
4010 pair.first, connection->getInputChannelName().c_str(),
4011 connection->getWindowName().c_str(), connection->getStatusLabel(),
4012 toString(connection->monitor),
4013 toString(connection->inputPublisherBlocked));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004014
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004015 if (!connection->outboundQueue.empty()) {
4016 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4017 connection->outboundQueue.size());
4018 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004019 dump.append(INDENT4);
4020 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004021 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004022 entry->targetFlags, entry->resolvedAction,
4023 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004024 }
4025 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004026 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004027 }
4028
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004029 if (!connection->waitQueue.empty()) {
4030 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4031 connection->waitQueue.size());
4032 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004033 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004034 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004035 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004036 "age=%0.1fms, wait=%0.1fms\n",
4037 entry->targetFlags, entry->resolvedAction,
4038 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
4039 (currentTime - entry->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004040 }
4041 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004042 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004043 }
4044 }
4045 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004046 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004047 }
4048
4049 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004050 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004051 (mAppSwitchDueTime - now()) / 1000000.0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004052 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004053 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004054 }
4055
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004056 dump += INDENT "Configuration:\n";
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004057 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004058 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004059 mConfig.keyRepeatTimeout * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004060}
4061
Michael Wright3dd60e22019-03-27 22:06:44 +00004062void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4063 const size_t numMonitors = monitors.size();
4064 for (size_t i = 0; i < numMonitors; i++) {
4065 const Monitor& monitor = monitors[i];
4066 const sp<InputChannel>& channel = monitor.inputChannel;
4067 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4068 dump += "\n";
4069 }
4070}
4071
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004072status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004073#if DEBUG_REGISTRATION
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004074 ALOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004075#endif
4076
4077 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004078 std::scoped_lock _l(mLock);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004079 sp<Connection> existingConnection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004080 if (existingConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004081 ALOGW("Attempted to register already registered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004082 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004083 return BAD_VALUE;
4084 }
4085
Michael Wright3dd60e22019-03-27 22:06:44 +00004086 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004087
4088 int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004089 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004090 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004091
Michael Wrightd02c5b62014-02-10 15:10:22 -08004092 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4093 } // release lock
4094
4095 // Wake the looper because some connections have changed.
4096 mLooper->wake();
4097 return OK;
4098}
4099
Michael Wright3dd60e22019-03-27 22:06:44 +00004100status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004101 int32_t displayId, bool isGestureMonitor) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004102 { // acquire lock
4103 std::scoped_lock _l(mLock);
4104
4105 if (displayId < 0) {
4106 ALOGW("Attempted to register input monitor without a specified display.");
4107 return BAD_VALUE;
4108 }
4109
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004110 if (inputChannel->getConnectionToken() == nullptr) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004111 ALOGW("Attempted to register input monitor without an identifying token.");
4112 return BAD_VALUE;
4113 }
4114
4115 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
4116
4117 const int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004118 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004119 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004120
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004121 auto& monitorsByDisplay =
4122 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Michael Wright3dd60e22019-03-27 22:06:44 +00004123 monitorsByDisplay[displayId].emplace_back(inputChannel);
4124
4125 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004126 }
4127 // Wake the looper because some connections have changed.
4128 mLooper->wake();
4129 return OK;
4130}
4131
Michael Wrightd02c5b62014-02-10 15:10:22 -08004132status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
4133#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004134 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004135#endif
4136
4137 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004138 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004139
4140 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
4141 if (status) {
4142 return status;
4143 }
4144 } // release lock
4145
4146 // Wake the poll loop because removing the connection may have changed the current
4147 // synchronization state.
4148 mLooper->wake();
4149 return OK;
4150}
4151
4152status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004153 bool notify) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004154 sp<Connection> connection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004155 if (connection == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004156 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004157 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004158 return BAD_VALUE;
4159 }
4160
John Recke0710582019-09-26 13:46:12 -07004161 [[maybe_unused]] const bool removed = removeByValue(mConnectionsByFd, connection);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004162 ALOG_ASSERT(removed);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004163 mInputChannelsByToken.erase(inputChannel->getConnectionToken());
Robert Carr5c8a0262018-10-03 16:30:44 -07004164
Michael Wrightd02c5b62014-02-10 15:10:22 -08004165 if (connection->monitor) {
4166 removeMonitorChannelLocked(inputChannel);
4167 }
4168
4169 mLooper->removeFd(inputChannel->getFd());
4170
4171 nsecs_t currentTime = now();
4172 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4173
4174 connection->status = Connection::STATUS_ZOMBIE;
4175 return OK;
4176}
4177
4178void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004179 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4180 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4181}
4182
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004183void InputDispatcher::removeMonitorChannelLocked(
4184 const sp<InputChannel>& inputChannel,
Michael Wright3dd60e22019-03-27 22:06:44 +00004185 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004186 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004187 std::vector<Monitor>& monitors = it->second;
4188 const size_t numMonitors = monitors.size();
4189 for (size_t i = 0; i < numMonitors; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004190 if (monitors[i].inputChannel == inputChannel) {
4191 monitors.erase(monitors.begin() + i);
4192 break;
4193 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004194 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004195 if (monitors.empty()) {
4196 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004197 } else {
4198 ++it;
4199 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004200 }
4201}
4202
Michael Wright3dd60e22019-03-27 22:06:44 +00004203status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4204 { // acquire lock
4205 std::scoped_lock _l(mLock);
4206 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4207
4208 if (!foundDisplayId) {
4209 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4210 return BAD_VALUE;
4211 }
4212 int32_t displayId = foundDisplayId.value();
4213
4214 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4215 if (stateIndex < 0) {
4216 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4217 return BAD_VALUE;
4218 }
4219
4220 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4221 std::optional<int32_t> foundDeviceId;
4222 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004223 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004224 foundDeviceId = state.deviceId;
4225 }
4226 }
4227 if (!foundDeviceId || !state.down) {
4228 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004229 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004230 return BAD_VALUE;
4231 }
4232 int32_t deviceId = foundDeviceId.value();
4233
4234 // Send cancel events to all the input channels we're stealing from.
4235 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004236 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004237 options.deviceId = deviceId;
4238 options.displayId = displayId;
4239 for (const TouchedWindow& window : state.windows) {
4240 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004241 if (channel != nullptr) {
4242 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4243 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004244 }
4245 // Then clear the current touch state so we stop dispatching to them as well.
4246 state.filterNonMonitors();
4247 }
4248 return OK;
4249}
4250
Michael Wright3dd60e22019-03-27 22:06:44 +00004251std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4252 const sp<IBinder>& token) {
4253 for (const auto& it : mGestureMonitorsByDisplay) {
4254 const std::vector<Monitor>& monitors = it.second;
4255 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004256 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004257 return it.first;
4258 }
4259 }
4260 }
4261 return std::nullopt;
4262}
4263
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004264sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) {
4265 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004266 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004267 }
4268
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004269 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004270 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004271 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004272 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004273 }
4274 }
Robert Carr4e670e52018-08-15 13:26:12 -07004275
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004276 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004277}
4278
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004279void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4280 const sp<Connection>& connection, uint32_t seq,
4281 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004282 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4283 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004284 commandEntry->connection = connection;
4285 commandEntry->eventTime = currentTime;
4286 commandEntry->seq = seq;
4287 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004288 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004289}
4290
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004291void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4292 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004293 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004294 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004295
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004296 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4297 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004298 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004299 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004300}
4301
chaviw0c06c6e2019-01-09 13:27:07 -08004302void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004303 const sp<InputWindowHandle>& newFocus) {
chaviw0c06c6e2019-01-09 13:27:07 -08004304 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4305 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004306 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4307 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004308 commandEntry->oldToken = oldToken;
4309 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004310 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004311}
4312
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004313void InputDispatcher::onANRLocked(nsecs_t currentTime,
4314 const sp<InputApplicationHandle>& applicationHandle,
4315 const sp<InputWindowHandle>& windowHandle, nsecs_t eventTime,
4316 nsecs_t waitStartTime, const char* reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004317 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4318 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4319 ALOGI("Application is not responding: %s. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004320 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
4321 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), dispatchLatency,
4322 waitDuration, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004323
4324 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004325 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004326 struct tm tm;
4327 localtime_r(&t, &tm);
4328 char timestr[64];
4329 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4330 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004331 mLastANRState += INDENT "ANR:\n";
4332 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004333 mLastANRState +=
4334 StringPrintf(INDENT2 "Window: %s\n",
4335 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004336 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4337 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4338 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004339 dumpDispatchStateLocked(mLastANRState);
4340
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004341 std::unique_ptr<CommandEntry> commandEntry =
4342 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004343 commandEntry->inputApplicationHandle = applicationHandle;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004344 commandEntry->inputChannel =
4345 windowHandle != nullptr ? getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004346 commandEntry->reason = reason;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004347 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004348}
4349
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004350void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004351 mLock.unlock();
4352
4353 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4354
4355 mLock.lock();
4356}
4357
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004358void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004359 sp<Connection> connection = commandEntry->connection;
4360
4361 if (connection->status != Connection::STATUS_ZOMBIE) {
4362 mLock.unlock();
4363
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004364 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004365
4366 mLock.lock();
4367 }
4368}
4369
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004370void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004371 sp<IBinder> oldToken = commandEntry->oldToken;
4372 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004373 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004374 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004375 mLock.lock();
4376}
4377
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004378void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004379 sp<IBinder> token =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004380 commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004381 mLock.unlock();
4382
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004383 nsecs_t newTimeout =
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004384 mPolicy->notifyANR(commandEntry->inputApplicationHandle, token, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004385
4386 mLock.lock();
4387
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004388 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004389}
4390
4391void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4392 CommandEntry* commandEntry) {
4393 KeyEntry* entry = commandEntry->keyEntry;
4394
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004395 KeyEvent event = createKeyEvent(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004396
4397 mLock.unlock();
4398
Michael Wright2b3c3302018-03-02 17:19:13 +00004399 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004400 sp<IBinder> token = commandEntry->inputChannel != nullptr
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004401 ? commandEntry->inputChannel->getConnectionToken()
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004402 : nullptr;
4403 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004404 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4405 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004406 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004407 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004408
4409 mLock.lock();
4410
4411 if (delay < 0) {
4412 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4413 } else if (!delay) {
4414 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4415 } else {
4416 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4417 entry->interceptKeyWakeupTime = now() + delay;
4418 }
4419 entry->release();
4420}
4421
chaviwfd6d3512019-03-25 13:23:49 -07004422void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4423 mLock.unlock();
4424 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4425 mLock.lock();
4426}
4427
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004428void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004429 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004430 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004431 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004432 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004433
4434 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07004435 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004436 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004437 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004438 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004439 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004440
4441 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4442 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4443 std::string msg =
4444 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4445 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4446 dispatchEntry->eventEntry->appendDescription(msg);
4447 ALOGI("%s", msg.c_str());
4448 }
4449
4450 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004451 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004452 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4453 restartEvent =
4454 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004455 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004456 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4457 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4458 handled);
4459 } else {
4460 restartEvent = false;
4461 }
4462
4463 // Dequeue the event and start the next cycle.
4464 // Note that because the lock might have been released, it is possible that the
4465 // contents of the wait queue to have been drained, so we need to double-check
4466 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004467 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4468 if (dispatchEntryIt != connection->waitQueue.end()) {
4469 dispatchEntry = *dispatchEntryIt;
4470 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004471 traceWaitQueueLength(connection);
4472 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004473 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004474 traceOutboundQueueLength(connection);
4475 } else {
4476 releaseDispatchEntry(dispatchEntry);
4477 }
4478 }
4479
4480 // Start the next dispatch cycle for this connection.
4481 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004482}
4483
4484bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004485 DispatchEntry* dispatchEntry,
4486 KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004487 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004488 if (!handled) {
4489 // Report the key as unhandled, since the fallback was not handled.
4490 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4491 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004492 return false;
4493 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004494
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004495 // Get the fallback key state.
4496 // Clear it out after dispatching the UP.
4497 int32_t originalKeyCode = keyEntry->keyCode;
4498 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4499 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4500 connection->inputState.removeFallbackKey(originalKeyCode);
4501 }
4502
4503 if (handled || !dispatchEntry->hasForegroundTarget()) {
4504 // If the application handles the original key for which we previously
4505 // generated a fallback or if the window is not a foreground window,
4506 // then cancel the associated fallback key, if any.
4507 if (fallbackKeyCode != -1) {
4508 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004509#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004510 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004511 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4512 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4513 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004514#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004515 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004516 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004517
4518 mLock.unlock();
4519
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004520 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004521 keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004522
4523 mLock.lock();
4524
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004525 // Cancel the fallback key.
4526 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004527 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004528 "application handled the original non-fallback key "
4529 "or is no longer a foreground target, "
4530 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004531 options.keyCode = fallbackKeyCode;
4532 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004533 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004534 connection->inputState.removeFallbackKey(originalKeyCode);
4535 }
4536 } else {
4537 // If the application did not handle a non-fallback key, first check
4538 // that we are in a good state to perform unhandled key event processing
4539 // Then ask the policy what to do with it.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004540 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN && keyEntry->repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004541 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004542#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004543 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004544 "since this is not an initial down. "
4545 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4546 originalKeyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004547#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004548 return false;
4549 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004550
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004551 // Dispatch the unhandled key to the policy.
4552#if DEBUG_OUTBOUND_EVENT_DETAILS
4553 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004554 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4555 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004556#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004557 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004558
4559 mLock.unlock();
4560
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004561 bool fallback =
4562 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
4563 &event, keyEntry->policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004564
4565 mLock.lock();
4566
4567 if (connection->status != Connection::STATUS_NORMAL) {
4568 connection->inputState.removeFallbackKey(originalKeyCode);
4569 return false;
4570 }
4571
4572 // Latch the fallback keycode for this key on an initial down.
4573 // The fallback keycode cannot change at any other point in the lifecycle.
4574 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004575 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004576 fallbackKeyCode = event.getKeyCode();
4577 } else {
4578 fallbackKeyCode = AKEYCODE_UNKNOWN;
4579 }
4580 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4581 }
4582
4583 ALOG_ASSERT(fallbackKeyCode != -1);
4584
4585 // Cancel the fallback key if the policy decides not to send it anymore.
4586 // We will continue to dispatch the key to the policy but we will no
4587 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004588 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
4589 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004590#if DEBUG_OUTBOUND_EVENT_DETAILS
4591 if (fallback) {
4592 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004593 "as a fallback for %d, but on the DOWN it had requested "
4594 "to send %d instead. Fallback canceled.",
4595 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004596 } else {
4597 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004598 "but on the DOWN it had requested to send %d. "
4599 "Fallback canceled.",
4600 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004601 }
4602#endif
4603
4604 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4605 "canceling fallback, policy no longer desires it");
4606 options.keyCode = fallbackKeyCode;
4607 synthesizeCancelationEventsForConnectionLocked(connection, options);
4608
4609 fallback = false;
4610 fallbackKeyCode = AKEYCODE_UNKNOWN;
4611 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004612 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004613 }
4614 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004615
4616#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004617 {
4618 std::string msg;
4619 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4620 connection->inputState.getFallbackKeys();
4621 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004622 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004623 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004624 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004625 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004626 }
4627#endif
4628
4629 if (fallback) {
4630 // Restart the dispatch cycle using the fallback key.
4631 keyEntry->eventTime = event.getEventTime();
4632 keyEntry->deviceId = event.getDeviceId();
4633 keyEntry->source = event.getSource();
4634 keyEntry->displayId = event.getDisplayId();
4635 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4636 keyEntry->keyCode = fallbackKeyCode;
4637 keyEntry->scanCode = event.getScanCode();
4638 keyEntry->metaState = event.getMetaState();
4639 keyEntry->repeatCount = event.getRepeatCount();
4640 keyEntry->downTime = event.getDownTime();
4641 keyEntry->syntheticRepeat = false;
4642
4643#if DEBUG_OUTBOUND_EVENT_DETAILS
4644 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004645 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4646 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004647#endif
4648 return true; // restart the event
4649 } else {
4650#if DEBUG_OUTBOUND_EVENT_DETAILS
4651 ALOGD("Unhandled key event: No fallback key.");
4652#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004653
4654 // Report the key as unhandled, since there is no fallback key.
4655 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004656 }
4657 }
4658 return false;
4659}
4660
4661bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004662 DispatchEntry* dispatchEntry,
4663 MotionEntry* motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004664 return false;
4665}
4666
4667void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4668 mLock.unlock();
4669
4670 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4671
4672 mLock.lock();
4673}
4674
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004675KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
4676 KeyEvent event;
4677 event.initialize(entry.deviceId, entry.source, entry.displayId, entry.action, entry.flags,
4678 entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount,
4679 entry.downTime, entry.eventTime);
4680 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004681}
4682
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004683void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004684 int32_t injectionResult,
4685 nsecs_t timeSpentWaitingForApplication) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004686 // TODO Write some statistics about how long we spend waiting.
4687}
4688
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05004689/**
4690 * Report the touch event latency to the statsd server.
4691 * Input events are reported for statistics if:
4692 * - This is a touchscreen event
4693 * - InputFilter is not enabled
4694 * - Event is not injected or synthesized
4695 *
4696 * Statistics should be reported before calling addValue, to prevent a fresh new sample
4697 * from getting aggregated with the "old" data.
4698 */
4699void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
4700 REQUIRES(mLock) {
4701 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
4702 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
4703 if (!reportForStatistics) {
4704 return;
4705 }
4706
4707 if (mTouchStatistics.shouldReport()) {
4708 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
4709 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
4710 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
4711 mTouchStatistics.reset();
4712 }
4713 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
4714 mTouchStatistics.addValue(latencyMicros);
4715}
4716
Michael Wrightd02c5b62014-02-10 15:10:22 -08004717void InputDispatcher::traceInboundQueueLengthLocked() {
4718 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004719 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004720 }
4721}
4722
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004723void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004724 if (ATRACE_ENABLED()) {
4725 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004726 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004727 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004728 }
4729}
4730
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004731void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004732 if (ATRACE_ENABLED()) {
4733 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004734 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004735 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004736 }
4737}
4738
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004739void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004740 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004741
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004742 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004743 dumpDispatchStateLocked(dump);
4744
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004745 if (!mLastANRState.empty()) {
4746 dump += "\nInput Dispatcher State at time of last ANR:\n";
4747 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004748 }
4749}
4750
4751void InputDispatcher::monitor() {
4752 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004753 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004754 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004755 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004756}
4757
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08004758/**
4759 * Wake up the dispatcher and wait until it processes all events and commands.
4760 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
4761 * this method can be safely called from any thread, as long as you've ensured that
4762 * the work you are interested in completing has already been queued.
4763 */
4764bool InputDispatcher::waitForIdle() {
4765 /**
4766 * Timeout should represent the longest possible time that a device might spend processing
4767 * events and commands.
4768 */
4769 constexpr std::chrono::duration TIMEOUT = 100ms;
4770 std::unique_lock lock(mLock);
4771 mLooper->wake();
4772 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
4773 return result == std::cv_status::no_timeout;
4774}
4775
Garfield Tane84e6f92019-08-29 17:28:41 -07004776} // namespace android::inputdispatcher