blob: 6a56d382986f525e4202ab0fa59890d6ad0a176b [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
31// Log debug messages about registrations.
32#define DEBUG_REGISTRATION 0
33
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
Siarhei Vishniakou86587282019-09-09 18:20:15 +010038static constexpr bool DEBUG_FOCUS = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -080039
40// Log debug messages about the app switch latency optimization.
41#define DEBUG_APP_SWITCH 0
42
43// Log debug messages about hover events.
44#define DEBUG_HOVER 0
45
46#include "InputDispatcher.h"
47
Garfield Tane84e6f92019-08-29 17:28:41 -070048#include "Connection.h"
49
Michael Wrightd02c5b62014-02-10 15:10:22 -080050#include <errno.h>
Siarhei Vishniakou443ad902019-03-06 17:25:41 -080051#include <inttypes.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080052#include <limits.h>
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -050053#include <statslog.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070054#include <stddef.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080055#include <time.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070056#include <unistd.h>
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -070057#include <queue>
58#include <sstream>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070059
Michael Wright2b3c3302018-03-02 17:19:13 +000060#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080061#include <android-base/stringprintf.h>
Robert Carr4e670e52018-08-15 13:26:12 -070062#include <binder/Binder.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070063#include <log/log.h>
64#include <powermanager/PowerManager.h>
65#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080066
67#define INDENT " "
68#define INDENT2 " "
69#define INDENT3 " "
70#define INDENT4 " "
71
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080072using android::base::StringPrintf;
73
Garfield Tane84e6f92019-08-29 17:28:41 -070074namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080075
76// Default input dispatching timeout if there is no focused application or paused window
77// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000078constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080079
80// Amount of time to allow for all pending events to be processed when an app switch
81// key is on the way. This is used to preempt input dispatch and drop input events
82// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000083constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080084
85// Amount of time to allow for an event to be dispatched (measured since its eventTime)
86// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000087constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080088
89// Amount of time to allow touch events to be streamed out to a connection before requiring
90// that the first event be finished. This value extends the ANR timeout by the specified
91// amount. For example, if streaming is allowed to get ahead by one second relative to the
92// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000093constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080094
95// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +000096constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
97
98// Log a warning when an interception call takes longer than this to process.
99constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800100
101// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000102constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
103
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104static inline nsecs_t now() {
105 return systemTime(SYSTEM_TIME_MONOTONIC);
106}
107
108static inline const char* toString(bool value) {
109 return value ? "true" : "false";
110}
111
112static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700113 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
114 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115}
116
117static bool isValidKeyAction(int32_t action) {
118 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700119 case AKEY_EVENT_ACTION_DOWN:
120 case AKEY_EVENT_ACTION_UP:
121 return true;
122 default:
123 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800124 }
125}
126
127static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700128 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800129 ALOGE("Key event has invalid action code 0x%x", action);
130 return false;
131 }
132 return true;
133}
134
Michael Wright7b159c92015-05-14 14:48:03 +0100135static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800136 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700137 case AMOTION_EVENT_ACTION_DOWN:
138 case AMOTION_EVENT_ACTION_UP:
139 case AMOTION_EVENT_ACTION_CANCEL:
140 case AMOTION_EVENT_ACTION_MOVE:
141 case AMOTION_EVENT_ACTION_OUTSIDE:
142 case AMOTION_EVENT_ACTION_HOVER_ENTER:
143 case AMOTION_EVENT_ACTION_HOVER_MOVE:
144 case AMOTION_EVENT_ACTION_HOVER_EXIT:
145 case AMOTION_EVENT_ACTION_SCROLL:
146 return true;
147 case AMOTION_EVENT_ACTION_POINTER_DOWN:
148 case AMOTION_EVENT_ACTION_POINTER_UP: {
149 int32_t index = getMotionEventActionPointerIndex(action);
150 return index >= 0 && index < pointerCount;
151 }
152 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
153 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
154 return actionButton != 0;
155 default:
156 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800157 }
158}
159
Michael Wright7b159c92015-05-14 14:48:03 +0100160static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700161 const PointerProperties* pointerProperties) {
162 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800163 ALOGE("Motion event has invalid action code 0x%x", action);
164 return false;
165 }
166 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000167 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700168 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800169 return false;
170 }
171 BitSet32 pointerIdBits;
172 for (size_t i = 0; i < pointerCount; i++) {
173 int32_t id = pointerProperties[i].id;
174 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700175 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
176 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800177 return false;
178 }
179 if (pointerIdBits.hasBit(id)) {
180 ALOGE("Motion event has duplicate pointer id %d", id);
181 return false;
182 }
183 pointerIdBits.markBit(id);
184 }
185 return true;
186}
187
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800188static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800189 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800190 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800191 return;
192 }
193
194 bool first = true;
195 Region::const_iterator cur = region.begin();
196 Region::const_iterator const tail = region.end();
197 while (cur != tail) {
198 if (first) {
199 first = false;
200 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800201 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800202 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800203 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 cur++;
205 }
206}
207
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700208/**
209 * Find the entry in std::unordered_map by key, and return it.
210 * If the entry is not found, return a default constructed entry.
211 *
212 * Useful when the entries are vectors, since an empty vector will be returned
213 * if the entry is not found.
214 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
215 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700216template <typename K, typename V>
217static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700218 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700219 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800220}
221
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700222/**
223 * Find the entry in std::unordered_map by value, and remove it.
224 * If more than one entry has the same value, then all matching
225 * key-value pairs will be removed.
226 *
227 * Return true if at least one value has been removed.
228 */
229template <typename K, typename V>
230static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
231 bool removed = false;
232 for (auto it = map.begin(); it != map.end();) {
233 if (it->second == value) {
234 it = map.erase(it);
235 removed = true;
236 } else {
237 it++;
238 }
239 }
240 return removed;
241}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800242
chaviwaf87b3e2019-10-01 16:59:28 -0700243static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
244 if (first == second) {
245 return true;
246 }
247
248 if (first == nullptr || second == nullptr) {
249 return false;
250 }
251
252 return first->getToken() == second->getToken();
253}
254
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800255static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
256 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
257}
258
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000259static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
260 EventEntry* eventEntry,
261 int32_t inputTargetFlags) {
262 if (inputTarget.useDefaultPointerInfo()) {
263 const PointerInfo& pointerInfo = inputTarget.getDefaultPointerInfo();
264 return std::make_unique<DispatchEntry>(eventEntry, // increments ref
265 inputTargetFlags, pointerInfo.xOffset,
266 pointerInfo.yOffset, inputTarget.globalScaleFactor,
267 pointerInfo.windowXScale, pointerInfo.windowYScale);
268 }
269
270 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
271 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
272
273 PointerCoords pointerCoords[motionEntry.pointerCount];
274
275 // Use the first pointer information to normalize all other pointers. This could be any pointer
276 // as long as all other pointers are normalized to the same value and the final DispatchEntry
277 // uses the offset and scale for the normalized pointer.
278 const PointerInfo& firstPointerInfo =
279 inputTarget.pointerInfos[inputTarget.pointerIds.firstMarkedBit()];
280
281 // Iterate through all pointers in the event to normalize against the first.
282 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
283 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
284 uint32_t pointerId = uint32_t(pointerProperties.id);
285 const PointerInfo& currPointerInfo = inputTarget.pointerInfos[pointerId];
286
287 // The scale factor is the ratio of the current pointers scale to the normalized scale.
288 float scaleXDiff = currPointerInfo.windowXScale / firstPointerInfo.windowXScale;
289 float scaleYDiff = currPointerInfo.windowYScale / firstPointerInfo.windowYScale;
290
291 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
292 // First apply the current pointers offset to set the window at 0,0
293 pointerCoords[pointerIndex].applyOffset(currPointerInfo.xOffset, currPointerInfo.yOffset);
294 // Next scale the coordinates.
295 pointerCoords[pointerIndex].scale(1, scaleXDiff, scaleYDiff);
296 // Lastly, offset the coordinates so they're in the normalized pointer's frame.
297 pointerCoords[pointerIndex].applyOffset(-firstPointerInfo.xOffset,
298 -firstPointerInfo.yOffset);
299 }
300
301 MotionEntry* combinedMotionEntry =
302 new MotionEntry(motionEntry.sequenceNum, motionEntry.eventTime, motionEntry.deviceId,
303 motionEntry.source, motionEntry.displayId, motionEntry.policyFlags,
304 motionEntry.action, motionEntry.actionButton, motionEntry.flags,
305 motionEntry.metaState, motionEntry.buttonState,
306 motionEntry.classification, motionEntry.edgeFlags,
307 motionEntry.xPrecision, motionEntry.yPrecision,
308 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
309 motionEntry.downTime, motionEntry.pointerCount,
310 motionEntry.pointerProperties, pointerCoords, 0 /* xOffset */,
311 0 /* yOffset */);
312
313 if (motionEntry.injectionState) {
314 combinedMotionEntry->injectionState = motionEntry.injectionState;
315 combinedMotionEntry->injectionState->refCount += 1;
316 }
317
318 std::unique_ptr<DispatchEntry> dispatchEntry =
319 std::make_unique<DispatchEntry>(combinedMotionEntry, // increments ref
320 inputTargetFlags, firstPointerInfo.xOffset,
321 firstPointerInfo.yOffset, inputTarget.globalScaleFactor,
322 firstPointerInfo.windowXScale,
323 firstPointerInfo.windowYScale);
324 combinedMotionEntry->release();
325 return dispatchEntry;
326}
327
Michael Wrightd02c5b62014-02-10 15:10:22 -0800328// --- InputDispatcher ---
329
Garfield Tan00f511d2019-06-12 16:55:40 -0700330InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
331 : mPolicy(policy),
332 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700333 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tan00f511d2019-06-12 16:55:40 -0700334 mAppSwitchSawKeyDown(false),
335 mAppSwitchDueTime(LONG_LONG_MAX),
336 mNextUnblockedEvent(nullptr),
337 mDispatchEnabled(false),
338 mDispatchFrozen(false),
339 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800340 // mInTouchMode will be initialized by the WindowManager to the default device config.
341 // To avoid leaking stack in case that call never comes, and for tests,
342 // initialize it here anyways.
343 mInTouchMode(true),
Garfield Tan00f511d2019-06-12 16:55:40 -0700344 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
345 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800346 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800347 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800348
Yi Kong9b14ac62018-07-17 13:48:38 -0700349 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800350
351 policy->getDispatcherConfiguration(&mConfig);
352}
353
354InputDispatcher::~InputDispatcher() {
355 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800356 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800357
358 resetKeyRepeatLocked();
359 releasePendingEventLocked();
360 drainInboundQueueLocked();
361 }
362
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700363 while (!mConnectionsByFd.empty()) {
364 sp<Connection> connection = mConnectionsByFd.begin()->second;
365 unregisterInputChannel(connection->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800366 }
367}
368
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700369status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700370 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700371 return ALREADY_EXISTS;
372 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700373 mThread = std::make_unique<InputThread>(
374 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
375 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700376}
377
378status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700379 if (mThread && mThread->isCallingThread()) {
380 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700381 return INVALID_OPERATION;
382 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700383 mThread.reset();
384 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700385}
386
Michael Wrightd02c5b62014-02-10 15:10:22 -0800387void InputDispatcher::dispatchOnce() {
388 nsecs_t nextWakeupTime = LONG_LONG_MAX;
389 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800390 std::scoped_lock _l(mLock);
391 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800392
393 // Run a dispatch loop if there are no pending commands.
394 // The dispatch loop might enqueue commands to run afterwards.
395 if (!haveCommandsLocked()) {
396 dispatchOnceInnerLocked(&nextWakeupTime);
397 }
398
399 // Run all pending commands if there are any.
400 // If any commands were run then force the next poll to wake up immediately.
401 if (runCommandsLockedInterruptible()) {
402 nextWakeupTime = LONG_LONG_MIN;
403 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800404
405 // We are about to enter an infinitely long sleep, because we have no commands or
406 // pending or queued events
407 if (nextWakeupTime == LONG_LONG_MAX) {
408 mDispatcherEnteredIdle.notify_all();
409 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800410 } // release lock
411
412 // Wait for callback or timeout or wake. (make sure we round up, not down)
413 nsecs_t currentTime = now();
414 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
415 mLooper->pollOnce(timeoutMillis);
416}
417
418void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
419 nsecs_t currentTime = now();
420
Jeff Browndc5992e2014-04-11 01:27:26 -0700421 // Reset the key repeat timer whenever normal dispatch is suspended while the
422 // device is in a non-interactive state. This is to ensure that we abort a key
423 // repeat if the device is just coming out of sleep.
424 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800425 resetKeyRepeatLocked();
426 }
427
428 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
429 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100430 if (DEBUG_FOCUS) {
431 ALOGD("Dispatch frozen. Waiting some more.");
432 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800433 return;
434 }
435
436 // Optimize latency of app switches.
437 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
438 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
439 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
440 if (mAppSwitchDueTime < *nextWakeupTime) {
441 *nextWakeupTime = mAppSwitchDueTime;
442 }
443
444 // Ready to start a new event.
445 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700446 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700447 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800448 if (isAppSwitchDue) {
449 // The inbound queue is empty so the app switch key we were waiting
450 // for will never arrive. Stop waiting for it.
451 resetPendingAppSwitchLocked(false);
452 isAppSwitchDue = false;
453 }
454
455 // Synthesize a key repeat if appropriate.
456 if (mKeyRepeatState.lastKeyEntry) {
457 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
458 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
459 } else {
460 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
461 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
462 }
463 }
464 }
465
466 // Nothing to do if there is no pending event.
467 if (!mPendingEvent) {
468 return;
469 }
470 } else {
471 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700472 mPendingEvent = mInboundQueue.front();
473 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800474 traceInboundQueueLengthLocked();
475 }
476
477 // Poke user activity for this event.
478 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700479 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800480 }
481
482 // Get ready to dispatch the event.
483 resetANRTimeoutsLocked();
484 }
485
486 // Now we have an event to dispatch.
487 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700488 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800489 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700490 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800491 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700492 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800493 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700494 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800495 }
496
497 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700498 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800499 }
500
501 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700502 case EventEntry::Type::CONFIGURATION_CHANGED: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700503 ConfigurationChangedEntry* typedEntry =
504 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
505 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700506 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700507 break;
508 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800509
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700510 case EventEntry::Type::DEVICE_RESET: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700511 DeviceResetEntry* typedEntry = static_cast<DeviceResetEntry*>(mPendingEvent);
512 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700513 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700514 break;
515 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800516
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100517 case EventEntry::Type::FOCUS: {
518 FocusEntry* typedEntry = static_cast<FocusEntry*>(mPendingEvent);
519 dispatchFocusLocked(currentTime, typedEntry);
520 done = true;
521 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
522 break;
523 }
524
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700525 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700526 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
527 if (isAppSwitchDue) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700528 if (isAppSwitchKeyEvent(*typedEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700529 resetPendingAppSwitchLocked(true);
530 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700531 } else if (dropReason == DropReason::NOT_DROPPED) {
532 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700533 }
534 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700535 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700536 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700537 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700538 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
539 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700540 }
541 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
542 break;
543 }
544
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700545 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700546 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700547 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
548 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800549 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700550 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700551 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700552 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700553 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
554 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700555 }
556 done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
557 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800558 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800559 }
560
561 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700562 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700563 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800564 }
Michael Wright3a981722015-06-10 15:26:13 +0100565 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800566
567 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700568 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800569 }
570}
571
572bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700573 bool needWake = mInboundQueue.empty();
574 mInboundQueue.push_back(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800575 traceInboundQueueLengthLocked();
576
577 switch (entry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700578 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700579 // Optimize app switch latency.
580 // If the application takes too long to catch up then we drop all events preceding
581 // the app switch key.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700582 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700583 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700584 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700585 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700586 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700587 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800588#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700589 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800590#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700591 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700592 mAppSwitchSawKeyDown = false;
593 needWake = true;
594 }
595 }
596 }
597 break;
598 }
599
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700600 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700601 // Optimize case where the current application is unresponsive and the user
602 // decides to touch a window in a different application.
603 // If the application takes too long to catch up then we drop all events preceding
604 // the touch into the other window.
605 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
606 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN &&
607 (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
608 mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY &&
609 mInputTargetWaitApplicationToken != nullptr) {
610 int32_t displayId = motionEntry->displayId;
611 int32_t x =
612 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
613 int32_t y =
614 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
615 sp<InputWindowHandle> touchedWindowHandle =
616 findTouchedWindowAtLocked(displayId, x, y);
617 if (touchedWindowHandle != nullptr &&
618 touchedWindowHandle->getApplicationToken() !=
619 mInputTargetWaitApplicationToken) {
620 // User touched a different application than the one we are waiting on.
621 // Flag the event, and start pruning the input queue.
622 mNextUnblockedEvent = motionEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800623 needWake = true;
624 }
625 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700626 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800627 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700628 case EventEntry::Type::CONFIGURATION_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100629 case EventEntry::Type::DEVICE_RESET:
630 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700631 // nothing to do
632 break;
633 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800634 }
635
636 return needWake;
637}
638
639void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
640 entry->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700641 mRecentQueue.push_back(entry);
642 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
643 mRecentQueue.front()->release();
644 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800645 }
646}
647
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700648sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
649 int32_t y, bool addOutsideTargets,
650 bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800651 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800652 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
653 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800654 const InputWindowInfo* windowInfo = windowHandle->getInfo();
655 if (windowInfo->displayId == displayId) {
656 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800657
658 if (windowInfo->visible) {
659 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700660 bool isTouchModal = (flags &
661 (InputWindowInfo::FLAG_NOT_FOCUSABLE |
662 InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800663 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800664 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700665 if (portalToDisplayId != ADISPLAY_ID_NONE &&
666 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800667 if (addPortalWindows) {
668 // For the monitoring channels of the display.
669 mTempTouchState.addPortalWindow(windowHandle);
670 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700671 return findTouchedWindowAtLocked(portalToDisplayId, x, y,
672 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800673 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800674 // Found window.
675 return windowHandle;
676 }
677 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800678
679 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700680 mTempTouchState.addOrUpdateWindow(windowHandle,
681 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
682 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800683 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800684 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800685 }
686 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700687 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800688}
689
Garfield Tane84e6f92019-08-29 17:28:41 -0700690std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +0000691 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
692 std::vector<TouchedMonitor> touchedMonitors;
693
694 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
695 addGestureMonitors(monitors, touchedMonitors);
696 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
697 const InputWindowInfo* windowInfo = portalWindow->getInfo();
698 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700699 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
700 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000701 }
702 return touchedMonitors;
703}
704
705void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700706 std::vector<TouchedMonitor>& outTouchedMonitors,
707 float xOffset, float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000708 if (monitors.empty()) {
709 return;
710 }
711 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
712 for (const Monitor& monitor : monitors) {
713 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
714 }
715}
716
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700717void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800718 const char* reason;
719 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700720 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800721#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700722 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800723#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700724 reason = "inbound event was dropped because the policy consumed it";
725 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700726 case DropReason::DISABLED:
727 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700728 ALOGI("Dropped event because input dispatch is disabled.");
729 }
730 reason = "inbound event was dropped because input dispatch is disabled";
731 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700732 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700733 ALOGI("Dropped event because of pending overdue app switch.");
734 reason = "inbound event was dropped because of pending overdue app switch";
735 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700736 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700737 ALOGI("Dropped event because the current application is not responding and the user "
738 "has started interacting with a different application.");
739 reason = "inbound event was dropped because the current application is not responding "
740 "and the user has started interacting with a different application";
741 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700742 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700743 ALOGI("Dropped event because it is stale.");
744 reason = "inbound event was dropped because it is stale";
745 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700746 case DropReason::NOT_DROPPED: {
747 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700748 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700749 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800750 }
751
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700752 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700753 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800754 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
755 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700756 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800757 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700758 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700759 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
760 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700761 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
762 synthesizeCancelationEventsForAllConnectionsLocked(options);
763 } else {
764 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
765 synthesizeCancelationEventsForAllConnectionsLocked(options);
766 }
767 break;
768 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100769 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700770 case EventEntry::Type::CONFIGURATION_CHANGED:
771 case EventEntry::Type::DEVICE_RESET: {
772 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
773 break;
774 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800775 }
776}
777
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800778static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700779 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
780 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800781}
782
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700783bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
784 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
785 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
786 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800787}
788
789bool InputDispatcher::isAppSwitchPendingLocked() {
790 return mAppSwitchDueTime != LONG_LONG_MAX;
791}
792
793void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
794 mAppSwitchDueTime = LONG_LONG_MAX;
795
796#if DEBUG_APP_SWITCH
797 if (handled) {
798 ALOGD("App switch has arrived.");
799 } else {
800 ALOGD("App switch was abandoned.");
801 }
802#endif
803}
804
Michael Wrightd02c5b62014-02-10 15:10:22 -0800805bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700806 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800807}
808
809bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700810 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800811 return false;
812 }
813
814 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700815 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700816 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800817 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700818 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800819
820 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700821 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800822 return true;
823}
824
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700825void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
826 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800827}
828
829void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700830 while (!mInboundQueue.empty()) {
831 EventEntry* entry = mInboundQueue.front();
832 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800833 releaseInboundEventLocked(entry);
834 }
835 traceInboundQueueLengthLocked();
836}
837
838void InputDispatcher::releasePendingEventLocked() {
839 if (mPendingEvent) {
840 resetANRTimeoutsLocked();
841 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700842 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800843 }
844}
845
846void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
847 InjectionState* injectionState = entry->injectionState;
848 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
849#if DEBUG_DISPATCH_CYCLE
850 ALOGD("Injected inbound event was dropped.");
851#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800852 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800853 }
854 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700855 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800856 }
857 addRecentEventLocked(entry);
858 entry->release();
859}
860
861void InputDispatcher::resetKeyRepeatLocked() {
862 if (mKeyRepeatState.lastKeyEntry) {
863 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700864 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800865 }
866}
867
Garfield Tane84e6f92019-08-29 17:28:41 -0700868KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800869 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
870
871 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700872 uint32_t policyFlags = entry->policyFlags &
873 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800874 if (entry->refCount == 1) {
875 entry->recycle();
876 entry->eventTime = currentTime;
877 entry->policyFlags = policyFlags;
878 entry->repeatCount += 1;
879 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700880 KeyEntry* newEntry =
881 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, entry->deviceId,
882 entry->source, entry->displayId, policyFlags, entry->action,
883 entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
884 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800885
886 mKeyRepeatState.lastKeyEntry = newEntry;
887 entry->release();
888
889 entry = newEntry;
890 }
891 entry->syntheticRepeat = true;
892
893 // Increment reference count since we keep a reference to the event in
894 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
895 entry->refCount += 1;
896
897 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
898 return entry;
899}
900
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700901bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
902 ConfigurationChangedEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800903#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700904 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800905#endif
906
907 // Reset key repeating in case a keyboard device was added or removed or something.
908 resetKeyRepeatLocked();
909
910 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700911 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
912 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800913 commandEntry->eventTime = entry->eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700914 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800915 return true;
916}
917
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700918bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceResetEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800919#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700920 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700921 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800922#endif
923
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700924 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800925 options.deviceId = entry->deviceId;
926 synthesizeCancelationEventsForAllConnectionsLocked(options);
927 return true;
928}
929
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100930void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) {
931 FocusEntry* focusEntry =
932 new FocusEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, now(), window.getToken(), hasFocus);
933 enqueueInboundEventLocked(focusEntry);
934}
935
936void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) {
937 sp<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
938 if (channel == nullptr) {
939 return; // Window has gone away
940 }
941 InputTarget target;
942 target.inputChannel = channel;
943 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
944 entry->dispatchInProgress = true;
945
946 dispatchEventLocked(currentTime, entry, {target});
947}
948
Michael Wrightd02c5b62014-02-10 15:10:22 -0800949bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700950 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800951 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700952 if (!entry->dispatchInProgress) {
953 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
954 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
955 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
956 if (mKeyRepeatState.lastKeyEntry &&
957 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800958 // We have seen two identical key downs in a row which indicates that the device
959 // driver is automatically generating key repeats itself. We take note of the
960 // repeat here, but we disable our own next key repeat timer since it is clear that
961 // we will not need to synthesize key repeats ourselves.
962 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
963 resetKeyRepeatLocked();
964 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
965 } else {
966 // Not a repeat. Save key down state in case we do see a repeat later.
967 resetKeyRepeatLocked();
968 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
969 }
970 mKeyRepeatState.lastKeyEntry = entry;
971 entry->refCount += 1;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700972 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800973 resetKeyRepeatLocked();
974 }
975
976 if (entry->repeatCount == 1) {
977 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
978 } else {
979 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
980 }
981
982 entry->dispatchInProgress = true;
983
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700984 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985 }
986
987 // Handle case where the policy asked us to try again later last time.
988 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
989 if (currentTime < entry->interceptKeyWakeupTime) {
990 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
991 *nextWakeupTime = entry->interceptKeyWakeupTime;
992 }
993 return false; // wait until next wakeup
994 }
995 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
996 entry->interceptKeyWakeupTime = 0;
997 }
998
999 // Give the policy a chance to intercept the key.
1000 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1001 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001002 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001003 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +08001004 sp<InputWindowHandle> focusedWindowHandle =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001005 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(*entry));
Tiger Huang721e26f2018-07-24 22:26:19 +08001006 if (focusedWindowHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001007 commandEntry->inputChannel = getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001008 }
1009 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001010 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001011 entry->refCount += 1;
1012 return false; // wait for the command to run
1013 } else {
1014 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1015 }
1016 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001017 if (*dropReason == DropReason::NOT_DROPPED) {
1018 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001019 }
1020 }
1021
1022 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001023 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001024 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001025 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001026 : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08001027 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001028 return true;
1029 }
1030
1031 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001032 std::vector<InputTarget> inputTargets;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001033 int32_t injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001034 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001035 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1036 return false;
1037 }
1038
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001039 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001040 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
1041 return true;
1042 }
1043
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001044 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001045 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001046
1047 // Dispatch the key.
1048 dispatchEventLocked(currentTime, entry, inputTargets);
1049 return true;
1050}
1051
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001052void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001053#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001054 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001055 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1056 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001057 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1058 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1059 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001060#endif
1061}
1062
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001063bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry,
1064 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001065 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001066 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001067 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001068 entry->dispatchInProgress = true;
1069
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001070 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001071 }
1072
1073 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001074 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001075 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001076 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001077 : INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001078 return true;
1079 }
1080
1081 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1082
1083 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001084 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001085
1086 bool conflictingPointerActions = false;
1087 int32_t injectionResult;
1088 if (isPointerEvent) {
1089 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001090 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001091 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001092 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001093 } else {
1094 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001095 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001096 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001097 }
1098 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1099 return false;
1100 }
1101
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001102 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001103 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001104 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001105 CancelationOptions::Mode mode(isPointerEvent
1106 ? CancelationOptions::CANCEL_POINTER_EVENTS
1107 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001108 CancelationOptions options(mode, "input event injection failed");
1109 synthesizeCancelationEventsForMonitorsLocked(options);
1110 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001111 return true;
1112 }
1113
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001114 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001115 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001116
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001117 if (isPointerEvent) {
1118 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1119 if (stateIndex >= 0) {
1120 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001121 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001122 // The event has gone through these portal windows, so we add monitoring targets of
1123 // the corresponding displays as well.
1124 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001125 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001126 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001127 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001128 }
1129 }
1130 }
1131 }
1132
Michael Wrightd02c5b62014-02-10 15:10:22 -08001133 // Dispatch the motion.
1134 if (conflictingPointerActions) {
1135 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001136 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001137 synthesizeCancelationEventsForAllConnectionsLocked(options);
1138 }
1139 dispatchEventLocked(currentTime, entry, inputTargets);
1140 return true;
1141}
1142
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001143void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001144#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001145 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001146 ", policyFlags=0x%x, "
1147 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1148 "metaState=0x%x, buttonState=0x%x,"
1149 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001150 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1151 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1152 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001153
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001154 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001155 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001156 "x=%f, y=%f, pressure=%f, size=%f, "
1157 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1158 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001159 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1160 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1161 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1162 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1163 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1164 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1165 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1166 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1167 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1168 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001169 }
1170#endif
1171}
1172
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001173void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* eventEntry,
1174 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001175 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001176#if DEBUG_DISPATCH_CYCLE
1177 ALOGD("dispatchEventToCurrentInputTargets");
1178#endif
1179
1180 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1181
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001182 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001183
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001184 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001185 sp<Connection> connection =
1186 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001187 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001188 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001189 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001190 if (DEBUG_FOCUS) {
1191 ALOGD("Dropping event delivery to target with channel '%s' because it "
1192 "is no longer registered with the input dispatcher.",
1193 inputTarget.inputChannel->getName().c_str());
1194 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001195 }
1196 }
1197}
1198
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001199int32_t InputDispatcher::handleTargetsNotReadyLocked(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001200 nsecs_t currentTime, const EventEntry& entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001201 const sp<InputApplicationHandle>& applicationHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001202 const sp<InputWindowHandle>& windowHandle, nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001203 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001204 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001205 if (DEBUG_FOCUS) {
1206 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1207 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001208 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1209 mInputTargetWaitStartTime = currentTime;
1210 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1211 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001212 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001213 }
1214 } else {
1215 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001216 if (DEBUG_FOCUS) {
1217 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
1218 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), reason);
1219 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001220 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001221 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001222 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001223 } else if (applicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001224 timeout =
1225 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001226 } else {
1227 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1228 }
1229
1230 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1231 mInputTargetWaitStartTime = currentTime;
1232 mInputTargetWaitTimeoutTime = currentTime + timeout;
1233 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001234 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001235
Yi Kong9b14ac62018-07-17 13:48:38 -07001236 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001237 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001238 }
Robert Carr740167f2018-10-11 19:03:41 -07001239 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1240 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001241 }
1242 }
1243 }
1244
1245 if (mInputTargetWaitTimeoutExpired) {
1246 return INPUT_EVENT_INJECTION_TIMED_OUT;
1247 }
1248
1249 if (currentTime >= mInputTargetWaitTimeoutTime) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001250 onANRLocked(currentTime, applicationHandle, windowHandle, entry.eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001251 mInputTargetWaitStartTime, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001252
1253 // Force poll loop to wake up immediately on next iteration once we get the
1254 // ANR response back from the policy.
1255 *nextWakeupTime = LONG_LONG_MIN;
1256 return INPUT_EVENT_INJECTION_PENDING;
1257 } else {
1258 // Force poll loop to wake up when timeout is due.
1259 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1260 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1261 }
1262 return INPUT_EVENT_INJECTION_PENDING;
1263 }
1264}
1265
Robert Carr803535b2018-08-02 16:38:15 -07001266void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1267 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1268 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1269 state.removeWindowByToken(token);
1270 }
1271}
1272
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001273void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001274 nsecs_t newTimeout, const sp<IBinder>& inputConnectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001275 if (newTimeout > 0) {
1276 // Extend the timeout.
1277 mInputTargetWaitTimeoutTime = now() + newTimeout;
1278 } else {
1279 // Give up.
1280 mInputTargetWaitTimeoutExpired = true;
1281
1282 // Input state will not be realistic. Mark it out of sync.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001283 sp<Connection> connection = getConnectionLocked(inputConnectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001284 if (connection != nullptr) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001285 removeWindowByTokenLocked(inputConnectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001286
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001287 if (connection->status == Connection::STATUS_NORMAL) {
1288 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1289 "application not responding");
1290 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001291 }
1292 }
1293 }
1294}
1295
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001296nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001297 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1298 return currentTime - mInputTargetWaitStartTime;
1299 }
1300 return 0;
1301}
1302
1303void InputDispatcher::resetANRTimeoutsLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001304 if (DEBUG_FOCUS) {
1305 ALOGD("Resetting ANR timeouts.");
1306 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001307
1308 // Reset input target wait timeout.
1309 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001310 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001311}
1312
Tiger Huang721e26f2018-07-24 22:26:19 +08001313/**
1314 * Get the display id that the given event should go to. If this event specifies a valid display id,
1315 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1316 * Focused display is the display that the user most recently interacted with.
1317 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001318int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001319 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001320 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001321 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001322 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1323 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001324 break;
1325 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001326 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001327 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1328 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001329 break;
1330 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001331 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001332 case EventEntry::Type::CONFIGURATION_CHANGED:
1333 case EventEntry::Type::DEVICE_RESET: {
1334 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001335 return ADISPLAY_ID_NONE;
1336 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001337 }
1338 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1339}
1340
Michael Wrightd02c5b62014-02-10 15:10:22 -08001341int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001342 const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001343 std::vector<InputTarget>& inputTargets,
1344 nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001345 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001346 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001347
Tiger Huang721e26f2018-07-24 22:26:19 +08001348 int32_t displayId = getTargetDisplayId(entry);
1349 sp<InputWindowHandle> focusedWindowHandle =
1350 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1351 sp<InputApplicationHandle> focusedApplicationHandle =
1352 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1353
Michael Wrightd02c5b62014-02-10 15:10:22 -08001354 // If there is no currently focused window and no focused application
1355 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001356 if (focusedWindowHandle == nullptr) {
1357 if (focusedApplicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001358 injectionResult =
1359 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1360 nullptr, nextWakeupTime,
1361 "Waiting because no window has focus but there is "
1362 "a focused application that may eventually add a "
1363 "window when it finishes starting up.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001364 goto Unresponsive;
1365 }
1366
Arthur Hung3b413f22018-10-26 18:05:34 +08001367 ALOGI("Dropping event because there is no focused window or focused application in display "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001368 "%" PRId32 ".",
1369 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001370 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1371 goto Failed;
1372 }
1373
1374 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001375 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001376 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1377 goto Failed;
1378 }
1379
Jeff Brownffb49772014-10-10 19:01:34 -07001380 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001381 reason = checkWindowReadyForMoreInputLocked(currentTime, focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001382 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001383 injectionResult =
1384 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1385 focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001386 goto Unresponsive;
1387 }
1388
1389 // Success! Output targets.
1390 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001391 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001392 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1393 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001394
1395 // Done.
1396Failed:
1397Unresponsive:
1398 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001399 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001400 if (DEBUG_FOCUS) {
1401 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1402 "timeSpentWaitingForApplication=%0.1fms",
1403 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1404 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001405 return injectionResult;
1406}
1407
1408int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001409 const MotionEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001410 std::vector<InputTarget>& inputTargets,
1411 nsecs_t* nextWakeupTime,
1412 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001413 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001414 enum InjectionPermission {
1415 INJECTION_PERMISSION_UNKNOWN,
1416 INJECTION_PERMISSION_GRANTED,
1417 INJECTION_PERMISSION_DENIED
1418 };
1419
Michael Wrightd02c5b62014-02-10 15:10:22 -08001420 // For security reasons, we defer updating the touch state until we are sure that
1421 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001422 int32_t displayId = entry.displayId;
1423 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001424 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1425
1426 // Update the touch state as needed based on the properties of the touch event.
1427 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1428 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1429 sp<InputWindowHandle> newHoverWindowHandle;
1430
Jeff Brownf086ddb2014-02-11 14:28:48 -08001431 // Copy current touch state into mTempTouchState.
1432 // This state is always reset at the end of this function, so if we don't find state
1433 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001434 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001435 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1436 if (oldStateIndex >= 0) {
1437 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1438 mTempTouchState.copyFrom(*oldState);
1439 }
1440
1441 bool isSplit = mTempTouchState.split;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001442 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0 &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001443 (mTempTouchState.deviceId != entry.deviceId || mTempTouchState.source != entry.source ||
1444 mTempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001445 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1446 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1447 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1448 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1449 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001450 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001451 bool wrongDevice = false;
1452 if (newGesture) {
1453 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001454 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001455 if (DEBUG_FOCUS) {
1456 ALOGD("Dropping event because a pointer for a different device is already down "
1457 "in display %" PRId32,
1458 displayId);
1459 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001460 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001461 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1462 switchedDevice = false;
1463 wrongDevice = true;
1464 goto Failed;
1465 }
1466 mTempTouchState.reset();
1467 mTempTouchState.down = down;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001468 mTempTouchState.deviceId = entry.deviceId;
1469 mTempTouchState.source = entry.source;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001470 mTempTouchState.displayId = displayId;
1471 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001472 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001473 if (DEBUG_FOCUS) {
1474 ALOGI("Dropping move event because a pointer for a different device is already active "
1475 "in display %" PRId32,
1476 displayId);
1477 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001478 // TODO: test multiple simultaneous input streams.
1479 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1480 switchedDevice = false;
1481 wrongDevice = true;
1482 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001483 }
1484
1485 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1486 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1487
Garfield Tan00f511d2019-06-12 16:55:40 -07001488 int32_t x;
1489 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001490 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001491 // Always dispatch mouse events to cursor position.
1492 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001493 x = int32_t(entry.xCursorPosition);
1494 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001495 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001496 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1497 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001498 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001499 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001500 sp<InputWindowHandle> newTouchedWindowHandle =
1501 findTouchedWindowAtLocked(displayId, x, y, isDown /*addOutsideTargets*/,
1502 true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001503
1504 std::vector<TouchedMonitor> newGestureMonitors = isDown
1505 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1506 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001507
Michael Wrightd02c5b62014-02-10 15:10:22 -08001508 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001509 if (newTouchedWindowHandle != nullptr &&
1510 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001511 // New window supports splitting, but we should never split mouse events.
1512 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001513 } else if (isSplit) {
1514 // New window does not support splitting but we have already split events.
1515 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001516 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001517 }
1518
1519 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001520 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001521 // Try to assign the pointer to the first foreground window we find, if there is one.
1522 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001523 }
1524
1525 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1526 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001527 "(%d, %d) in display %" PRId32 ".",
1528 x, y, displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00001529 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1530 goto Failed;
1531 }
1532
1533 if (newTouchedWindowHandle != nullptr) {
1534 // Set target flags.
1535 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1536 if (isSplit) {
1537 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001538 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001539 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1540 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1541 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1542 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1543 }
1544
1545 // Update hover state.
1546 if (isHoverAction) {
1547 newHoverWindowHandle = newTouchedWindowHandle;
1548 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1549 newHoverWindowHandle = mLastHoverWindowHandle;
1550 }
1551
1552 // Update the temporary touch state.
1553 BitSet32 pointerIds;
1554 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001555 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001556 pointerIds.markBit(pointerId);
1557 }
1558 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001559 }
1560
Michael Wright3dd60e22019-03-27 22:06:44 +00001561 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001562 } else {
1563 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1564
1565 // If the pointer is not currently down, then ignore the event.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001566 if (!mTempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001567 if (DEBUG_FOCUS) {
1568 ALOGD("Dropping event because the pointer is not down or we previously "
1569 "dropped the pointer down event in display %" PRId32,
1570 displayId);
1571 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001572 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1573 goto Failed;
1574 }
1575
1576 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001577 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001578 mTempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001579 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1580 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001581
1582 sp<InputWindowHandle> oldTouchedWindowHandle =
1583 mTempTouchState.getFirstForegroundWindowHandle();
1584 sp<InputWindowHandle> newTouchedWindowHandle =
1585 findTouchedWindowAtLocked(displayId, x, y);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001586 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1587 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001588 if (DEBUG_FOCUS) {
1589 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1590 oldTouchedWindowHandle->getName().c_str(),
1591 newTouchedWindowHandle->getName().c_str(), displayId);
1592 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001593 // Make a slippery exit from the old window.
1594 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001595 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1596 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001597
1598 // Make a slippery entrance into the new window.
1599 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1600 isSplit = true;
1601 }
1602
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001603 int32_t targetFlags =
1604 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605 if (isSplit) {
1606 targetFlags |= InputTarget::FLAG_SPLIT;
1607 }
1608 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1609 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1610 }
1611
1612 BitSet32 pointerIds;
1613 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001614 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001615 }
1616 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1617 }
1618 }
1619 }
1620
1621 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1622 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001623 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001624#if DEBUG_HOVER
1625 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001626 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001627#endif
1628 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001629 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT,
1630 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001631 }
1632
1633 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001634 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001635#if DEBUG_HOVER
1636 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001637 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001638#endif
1639 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001640 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1641 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001642 }
1643 }
1644
1645 // Check permission to inject into all touched foreground windows and ensure there
1646 // is at least one touched foreground window.
1647 {
1648 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001649 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001650 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1651 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001652 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001653 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1654 injectionPermission = INJECTION_PERMISSION_DENIED;
1655 goto Failed;
1656 }
1657 }
1658 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001659 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1660 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001661 if (DEBUG_FOCUS) {
1662 ALOGD("Dropping event because there is no touched foreground window in display "
1663 "%" PRId32 " or gesture monitor to receive it.",
1664 displayId);
1665 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001666 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1667 goto Failed;
1668 }
1669
1670 // Permission granted to injection into all touched foreground windows.
1671 injectionPermission = INJECTION_PERMISSION_GRANTED;
1672 }
1673
1674 // Check whether windows listening for outside touches are owned by the same UID. If it is
1675 // set the policy flag that we will not reveal coordinate information to this window.
1676 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1677 sp<InputWindowHandle> foregroundWindowHandle =
1678 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001679 if (foregroundWindowHandle) {
1680 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1681 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1682 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1683 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1684 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1685 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001686 InputTarget::FLAG_ZERO_COORDS,
1687 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001688 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001689 }
1690 }
1691 }
1692 }
1693
1694 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001695 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001696 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001697 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001698 std::string reason =
1699 checkWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle,
1700 entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001701 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001702 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, nullptr,
1703 touchedWindow.windowHandle,
1704 nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001705 goto Unresponsive;
1706 }
1707 }
1708 }
1709
1710 // If this is the first pointer going down and the touched window has a wallpaper
1711 // then also add the touched wallpaper windows so they are locked in for the duration
1712 // of the touch gesture.
1713 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1714 // engine only supports touch events. We would need to add a mechanism similar
1715 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1716 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1717 sp<InputWindowHandle> foregroundWindowHandle =
1718 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001719 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001720 const std::vector<sp<InputWindowHandle>> windowHandles =
1721 getWindowHandlesLocked(displayId);
1722 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001723 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001724 if (info->displayId == displayId &&
1725 windowHandle->getInfo()->layoutParamsType == InputWindowInfo::TYPE_WALLPAPER) {
1726 mTempTouchState
1727 .addOrUpdateWindow(windowHandle,
1728 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1729 InputTarget::
1730 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1731 InputTarget::FLAG_DISPATCH_AS_IS,
1732 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001733 }
1734 }
1735 }
1736 }
1737
1738 // Success! Output targets.
1739 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1740
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001741 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001742 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001743 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001744 }
1745
Michael Wright3dd60e22019-03-27 22:06:44 +00001746 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1747 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001748 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00001749 }
1750
Michael Wrightd02c5b62014-02-10 15:10:22 -08001751 // Drop the outside or hover touch windows since we will not care about them
1752 // in the next iteration.
1753 mTempTouchState.filterNonAsIsTouchWindows();
1754
1755Failed:
1756 // Check injection permission once and for all.
1757 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001758 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001759 injectionPermission = INJECTION_PERMISSION_GRANTED;
1760 } else {
1761 injectionPermission = INJECTION_PERMISSION_DENIED;
1762 }
1763 }
1764
1765 // Update final pieces of touch state if the injector had permission.
1766 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1767 if (!wrongDevice) {
1768 if (switchedDevice) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001769 if (DEBUG_FOCUS) {
1770 ALOGD("Conflicting pointer actions: Switched to a different device.");
1771 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001772 *outConflictingPointerActions = true;
1773 }
1774
1775 if (isHoverAction) {
1776 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001777 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001778 if (DEBUG_FOCUS) {
1779 ALOGD("Conflicting pointer actions: Hover received while pointer was "
1780 "down.");
1781 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001782 *outConflictingPointerActions = true;
1783 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001784 mTempTouchState.reset();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001785 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1786 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001787 mTempTouchState.deviceId = entry.deviceId;
1788 mTempTouchState.source = entry.source;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001789 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001790 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001791 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
1792 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001793 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001794 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001795 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1796 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001797 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001798 if (DEBUG_FOCUS) {
1799 ALOGD("Conflicting pointer actions: Down received while already down.");
1800 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001801 *outConflictingPointerActions = true;
1802 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001803 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1804 // One pointer went up.
1805 if (isSplit) {
1806 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001807 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001808
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001809 for (size_t i = 0; i < mTempTouchState.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001810 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001811 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1812 touchedWindow.pointerIds.clearBit(pointerId);
1813 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001814 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001815 continue;
1816 }
1817 }
1818 i += 1;
1819 }
1820 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001821 }
1822
1823 // Save changes unless the action was scroll in which case the temporary touch
1824 // state was only valid for this one action.
1825 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1826 if (mTempTouchState.displayId >= 0) {
1827 if (oldStateIndex >= 0) {
1828 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1829 } else {
1830 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1831 }
1832 } else if (oldStateIndex >= 0) {
1833 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1834 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001835 }
1836
1837 // Update hover state.
1838 mLastHoverWindowHandle = newHoverWindowHandle;
1839 }
1840 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001841 if (DEBUG_FOCUS) {
1842 ALOGD("Not updating touch focus because injection was denied.");
1843 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001844 }
1845
1846Unresponsive:
1847 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1848 mTempTouchState.reset();
1849
1850 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001851 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001852 if (DEBUG_FOCUS) {
1853 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1854 "timeSpentWaitingForApplication=%0.1fms",
1855 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1856 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001857 return injectionResult;
1858}
1859
1860void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001861 int32_t targetFlags, BitSet32 pointerIds,
1862 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001863 std::vector<InputTarget>::iterator it =
1864 std::find_if(inputTargets.begin(), inputTargets.end(),
1865 [&windowHandle](const InputTarget& inputTarget) {
1866 return inputTarget.inputChannel->getConnectionToken() ==
1867 windowHandle->getToken();
1868 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00001869
Chavi Weingarten114b77f2020-01-15 22:35:10 +00001870 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001871
1872 if (it == inputTargets.end()) {
1873 InputTarget inputTarget;
1874 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1875 if (inputChannel == nullptr) {
1876 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1877 return;
1878 }
1879 inputTarget.inputChannel = inputChannel;
1880 inputTarget.flags = targetFlags;
1881 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
1882 inputTargets.push_back(inputTarget);
1883 it = inputTargets.end() - 1;
1884 }
1885
1886 ALOG_ASSERT(it->flags == targetFlags);
1887 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
1888
1889 it->addPointers(pointerIds, -windowInfo->frameLeft, -windowInfo->frameTop,
1890 windowInfo->windowXScale, windowInfo->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001891}
1892
Michael Wright3dd60e22019-03-27 22:06:44 +00001893void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001894 int32_t displayId, float xOffset,
1895 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001896 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1897 mGlobalMonitorsByDisplay.find(displayId);
1898
1899 if (it != mGlobalMonitorsByDisplay.end()) {
1900 const std::vector<Monitor>& monitors = it->second;
1901 for (const Monitor& monitor : monitors) {
1902 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001903 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001904 }
1905}
1906
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001907void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
1908 float yOffset,
1909 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001910 InputTarget target;
1911 target.inputChannel = monitor.inputChannel;
1912 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001913 target.setDefaultPointerInfo(xOffset, yOffset, 1 /* windowXScale */, 1 /* windowYScale */);
Michael Wright3dd60e22019-03-27 22:06:44 +00001914 inputTargets.push_back(target);
1915}
1916
Michael Wrightd02c5b62014-02-10 15:10:22 -08001917bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001918 const InjectionState* injectionState) {
1919 if (injectionState &&
1920 (windowHandle == nullptr ||
1921 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
1922 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001923 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001924 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001925 "owned by uid %d",
1926 injectionState->injectorPid, injectionState->injectorUid,
1927 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001928 } else {
1929 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001930 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001931 }
1932 return false;
1933 }
1934 return true;
1935}
1936
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001937bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
1938 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001939 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001940 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1941 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001942 if (otherHandle == windowHandle) {
1943 break;
1944 }
1945
1946 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001947 if (otherInfo->displayId == displayId && otherInfo->visible &&
1948 !otherInfo->isTrustedOverlay() && otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001949 return true;
1950 }
1951 }
1952 return false;
1953}
1954
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001955bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1956 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001957 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001958 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001959 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001960 if (otherHandle == windowHandle) {
1961 break;
1962 }
1963
1964 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001965 if (otherInfo->displayId == displayId && otherInfo->visible &&
1966 !otherInfo->isTrustedOverlay() && otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001967 return true;
1968 }
1969 }
1970 return false;
1971}
1972
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001973std::string InputDispatcher::checkWindowReadyForMoreInputLocked(
1974 nsecs_t currentTime, const sp<InputWindowHandle>& windowHandle,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001975 const EventEntry& eventEntry, const char* targetType) {
Jeff Brownffb49772014-10-10 19:01:34 -07001976 // If the window is paused then keep waiting.
1977 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001978 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001979 }
1980
1981 // If the window's connection is not registered then keep waiting.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001982 sp<Connection> connection = getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001983 if (connection == nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001984 return StringPrintf("Waiting because the %s window's input channel is not "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001985 "registered with the input dispatcher. The window may be in the "
1986 "process of being removed.",
1987 targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001988 }
1989
1990 // If the connection is dead then keep waiting.
Jeff Brownffb49772014-10-10 19:01:34 -07001991 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001992 return StringPrintf("Waiting because the %s window's input connection is %s."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001993 "The window may be in the process of being removed.",
1994 targetType, connection->getStatusLabel());
Jeff Brownffb49772014-10-10 19:01:34 -07001995 }
1996
1997 // If the connection is backed up then keep waiting.
1998 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001999 return StringPrintf("Waiting because the %s window's input channel is full. "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002000 "Outbound queue length: %zu. Wait queue length: %zu.",
2001 targetType, connection->outboundQueue.size(),
2002 connection->waitQueue.size());
Jeff Brownffb49772014-10-10 19:01:34 -07002003 }
2004
2005 // Ensure that the dispatch queues aren't too far backed up for this event.
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002006 if (eventEntry.type == EventEntry::Type::KEY) {
Jeff Brownffb49772014-10-10 19:01:34 -07002007 // If the event is a key event, then we must wait for all previous events to
2008 // complete before delivering it because previous events may have the
2009 // side-effect of transferring focus to a different window and we want to
2010 // ensure that the following keys are sent to the new window.
2011 //
2012 // Suppose the user touches a button in a window then immediately presses "A".
2013 // If the button causes a pop-up window to appear then we want to ensure that
2014 // the "A" key is delivered to the new pop-up window. This is because users
2015 // often anticipate pending UI changes when typing on a keyboard.
2016 // To obtain this behavior, we must serialize key events with respect to all
2017 // prior input events.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002018 if (!connection->outboundQueue.empty() || !connection->waitQueue.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002019 return StringPrintf("Waiting to send key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002020 "finished processing all of the input events that were previously "
2021 "delivered to it. Outbound queue length: %zu. Wait queue length: "
2022 "%zu.",
2023 targetType, connection->outboundQueue.size(),
2024 connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002025 }
Jeff Brownffb49772014-10-10 19:01:34 -07002026 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002027 // Touch events can always be sent to a window immediately because the user intended
2028 // to touch whatever was visible at the time. Even if focus changes or a new
2029 // window appears moments later, the touch event was meant to be delivered to
2030 // whatever window happened to be on screen at the time.
2031 //
2032 // Generic motion events, such as trackball or joystick events are a little trickier.
2033 // Like key events, generic motion events are delivered to the focused window.
2034 // Unlike key events, generic motion events don't tend to transfer focus to other
2035 // windows and it is not important for them to be serialized. So we prefer to deliver
2036 // generic motion events as soon as possible to improve efficiency and reduce lag
2037 // through batching.
2038 //
2039 // The one case where we pause input event delivery is when the wait queue is piling
2040 // up with lots of events because the application is not responding.
2041 // This condition ensures that ANRs are detected reliably.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002042 if (!connection->waitQueue.empty() &&
2043 currentTime >=
2044 connection->waitQueue.front()->deliveryTime + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002045 return StringPrintf("Waiting to send non-key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002046 "finished processing certain input events that were delivered to "
2047 "it over "
2048 "%0.1fms ago. Wait queue length: %zu. Wait queue head age: "
2049 "%0.1fms.",
2050 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
2051 connection->waitQueue.size(),
2052 (currentTime - connection->waitQueue.front()->deliveryTime) *
2053 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002054 }
2055 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002056 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002057}
2058
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002059std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002060 const sp<InputApplicationHandle>& applicationHandle,
2061 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002062 if (applicationHandle != nullptr) {
2063 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002064 std::string label(applicationHandle->getName());
2065 label += " - ";
2066 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067 return label;
2068 } else {
2069 return applicationHandle->getName();
2070 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002071 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002072 return windowHandle->getName();
2073 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002074 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002075 }
2076}
2077
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002078void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002079 if (eventEntry.type == EventEntry::Type::FOCUS) {
2080 // Focus events are passed to apps, but do not represent user activity.
2081 return;
2082 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002083 int32_t displayId = getTargetDisplayId(eventEntry);
2084 sp<InputWindowHandle> focusedWindowHandle =
2085 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
2086 if (focusedWindowHandle != nullptr) {
2087 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002088 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
2089#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002090 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002091#endif
2092 return;
2093 }
2094 }
2095
2096 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002097 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002098 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002099 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2100 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002101 return;
2102 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002103
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002104 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002105 eventType = USER_ACTIVITY_EVENT_TOUCH;
2106 }
2107 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002108 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002109 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002110 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2111 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002112 return;
2113 }
2114 eventType = USER_ACTIVITY_EVENT_BUTTON;
2115 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002116 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002117 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002118 case EventEntry::Type::CONFIGURATION_CHANGED:
2119 case EventEntry::Type::DEVICE_RESET: {
2120 LOG_ALWAYS_FATAL("%s events are not user activity",
2121 EventEntry::typeToString(eventEntry.type));
2122 break;
2123 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002124 }
2125
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002126 std::unique_ptr<CommandEntry> commandEntry =
2127 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002128 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002129 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002130 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002131}
2132
2133void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002134 const sp<Connection>& connection,
2135 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002136 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002137 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002138 std::string message =
2139 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2140 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002141 ATRACE_NAME(message.c_str());
2142 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002143#if DEBUG_DISPATCH_CYCLE
2144 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002145 "globalScaleFactor=%f, pointerIds=0x%x %s",
2146 connection->getInputChannelName().c_str(), inputTarget.flags,
2147 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2148 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002149#endif
2150
2151 // Skip this event if the connection status is not normal.
2152 // We don't want to enqueue additional outbound events if the connection is broken.
2153 if (connection->status != Connection::STATUS_NORMAL) {
2154#if DEBUG_DISPATCH_CYCLE
2155 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002156 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002157#endif
2158 return;
2159 }
2160
2161 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002162 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2163 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2164 "Entry type %s should not have FLAG_SPLIT",
2165 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002166
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002167 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002168 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002169 MotionEntry* splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002170 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002171 if (!splitMotionEntry) {
2172 return; // split event was dropped
2173 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002174 if (DEBUG_FOCUS) {
2175 ALOGD("channel '%s' ~ Split motion event.",
2176 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002177 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002178 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002179 enqueueDispatchEntriesLocked(currentTime, connection, splitMotionEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002180 splitMotionEntry->release();
2181 return;
2182 }
2183 }
2184
2185 // Not splitting. Enqueue dispatch entries for the event as is.
2186 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2187}
2188
2189void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002190 const sp<Connection>& connection,
2191 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002192 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002193 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002194 std::string message =
2195 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32
2196 ")",
2197 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002198 ATRACE_NAME(message.c_str());
2199 }
2200
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002201 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002202
2203 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002204 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002205 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002206 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002207 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002208 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002209 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002210 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002211 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002212 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002213 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002214 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002215 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002216
2217 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002218 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002219 startDispatchCycleLocked(currentTime, connection);
2220 }
2221}
2222
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002223void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
2224 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002225 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002226 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002227 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002228 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2229 connection->getInputChannelName().c_str(),
2230 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002231 ATRACE_NAME(message.c_str());
2232 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002233 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002234 if (!(inputTargetFlags & dispatchMode)) {
2235 return;
2236 }
2237 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2238
2239 // This is a new event.
2240 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002241 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002242 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002243
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002244 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2245 // different EventEntry than what was passed in.
2246 EventEntry* newEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002247 // Apply target flags and update the connection's input state.
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002248 switch (newEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002249 case EventEntry::Type::KEY: {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002250 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*newEntry);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002251 dispatchEntry->resolvedAction = keyEntry.action;
2252 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002253
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002254 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2255 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002256#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002257 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2258 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002259#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002260 return; // skip the inconsistent event
2261 }
2262 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002263 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002264
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002265 case EventEntry::Type::MOTION: {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002266 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*newEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002267 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2268 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2269 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2270 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2271 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2272 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2273 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2274 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2275 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2276 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2277 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002278 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002279 }
2280 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002281 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2282 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002283#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002284 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2285 "event",
2286 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002287#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002288 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2289 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002290
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002291 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002292 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2293 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2294 }
2295 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2296 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2297 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002298
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002299 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2300 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002301#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002302 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2303 "event",
2304 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002305#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002306 return; // skip the inconsistent event
2307 }
2308
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002309 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002310 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002311
2312 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002313 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002314 case EventEntry::Type::FOCUS: {
2315 break;
2316 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002317 case EventEntry::Type::CONFIGURATION_CHANGED:
2318 case EventEntry::Type::DEVICE_RESET: {
2319 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002320 EventEntry::typeToString(newEntry->type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002321 break;
2322 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002323 }
2324
2325 // Remember that we are waiting for this dispatch to complete.
2326 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002327 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002328 }
2329
2330 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002331 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002332 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002333}
2334
chaviwfd6d3512019-03-25 13:23:49 -07002335void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002336 const sp<IBinder>& newToken) {
chaviw8c9cf542019-03-25 13:02:48 -07002337 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002338 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2339 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002340 return;
2341 }
2342
2343 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2344 if (inputWindowHandle == nullptr) {
2345 return;
2346 }
2347
chaviw8c9cf542019-03-25 13:02:48 -07002348 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002349 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002350
2351 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2352
2353 if (!hasFocusChanged) {
2354 return;
2355 }
2356
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002357 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2358 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002359 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002360 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002361}
2362
2363void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002364 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002365 if (ATRACE_ENABLED()) {
2366 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002367 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002368 ATRACE_NAME(message.c_str());
2369 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002370#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002371 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002372#endif
2373
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002374 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2375 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002376 dispatchEntry->deliveryTime = currentTime;
2377
2378 // Publish the event.
2379 status_t status;
2380 EventEntry* eventEntry = dispatchEntry->eventEntry;
2381 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002382 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002383 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002384
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002385 // Publish the key event.
2386 status = connection->inputPublisher
2387 .publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId,
2388 keyEntry->source, keyEntry->displayId,
2389 dispatchEntry->resolvedAction,
2390 dispatchEntry->resolvedFlags, keyEntry->keyCode,
2391 keyEntry->scanCode, keyEntry->metaState,
2392 keyEntry->repeatCount, keyEntry->downTime,
2393 keyEntry->eventTime);
2394 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002395 }
2396
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002397 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002398 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002399
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002400 PointerCoords scaledCoords[MAX_POINTERS];
2401 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2402
2403 // Set the X and Y offset depending on the input source.
2404 float xOffset, yOffset;
2405 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
2406 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2407 float globalScaleFactor = dispatchEntry->globalScaleFactor;
2408 float wxs = dispatchEntry->windowXScale;
2409 float wys = dispatchEntry->windowYScale;
2410 xOffset = dispatchEntry->xOffset * wxs;
2411 yOffset = dispatchEntry->yOffset * wys;
2412 if (wxs != 1.0f || wys != 1.0f || globalScaleFactor != 1.0f) {
2413 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2414 scaledCoords[i] = motionEntry->pointerCoords[i];
2415 scaledCoords[i].scale(globalScaleFactor, wxs, wys);
2416 }
2417 usingCoords = scaledCoords;
2418 }
2419 } else {
2420 xOffset = 0.0f;
2421 yOffset = 0.0f;
2422
2423 // We don't want the dispatch target to know.
2424 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
2425 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2426 scaledCoords[i].clear();
2427 }
2428 usingCoords = scaledCoords;
2429 }
2430 }
2431
2432 // Publish the motion event.
2433 status = connection->inputPublisher
2434 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2435 motionEntry->source, motionEntry->displayId,
2436 dispatchEntry->resolvedAction,
2437 motionEntry->actionButton,
2438 dispatchEntry->resolvedFlags,
2439 motionEntry->edgeFlags, motionEntry->metaState,
2440 motionEntry->buttonState,
2441 motionEntry->classification, xOffset, yOffset,
2442 motionEntry->xPrecision,
2443 motionEntry->yPrecision,
2444 motionEntry->xCursorPosition,
2445 motionEntry->yCursorPosition,
2446 motionEntry->downTime, motionEntry->eventTime,
2447 motionEntry->pointerCount,
2448 motionEntry->pointerProperties, usingCoords);
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05002449 reportTouchEventForStatistics(*motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002450 break;
2451 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002452 case EventEntry::Type::FOCUS: {
2453 FocusEntry* focusEntry = static_cast<FocusEntry*>(eventEntry);
2454 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
2455 focusEntry->hasFocus,
2456 mInTouchMode);
2457 break;
2458 }
2459
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002460 case EventEntry::Type::CONFIGURATION_CHANGED:
2461 case EventEntry::Type::DEVICE_RESET: {
2462 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
2463 EventEntry::typeToString(eventEntry->type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002464 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002465 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002466 }
2467
2468 // Check the result.
2469 if (status) {
2470 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002471 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002472 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002473 "This is unexpected because the wait queue is empty, so the pipe "
2474 "should be empty and we shouldn't have any problems writing an "
2475 "event to it, status=%d",
2476 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002477 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2478 } else {
2479 // Pipe is full and we are waiting for the app to finish process some events
2480 // before sending more events to it.
2481#if DEBUG_DISPATCH_CYCLE
2482 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002483 "waiting for the application to catch up",
2484 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002485#endif
2486 connection->inputPublisherBlocked = true;
2487 }
2488 } else {
2489 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002490 "status=%d",
2491 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002492 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2493 }
2494 return;
2495 }
2496
2497 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002498 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2499 connection->outboundQueue.end(),
2500 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002501 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002502 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002503 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002504 }
2505}
2506
2507void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002508 const sp<Connection>& connection, uint32_t seq,
2509 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002510#if DEBUG_DISPATCH_CYCLE
2511 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002512 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002513#endif
2514
2515 connection->inputPublisherBlocked = false;
2516
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002517 if (connection->status == Connection::STATUS_BROKEN ||
2518 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002519 return;
2520 }
2521
2522 // Notify other system components and prepare to start the next dispatch cycle.
2523 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2524}
2525
2526void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002527 const sp<Connection>& connection,
2528 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002529#if DEBUG_DISPATCH_CYCLE
2530 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002531 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002532#endif
2533
2534 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002535 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002536 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002537 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002538 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002539
2540 // The connection appears to be unrecoverably broken.
2541 // Ignore already broken or zombie connections.
2542 if (connection->status == Connection::STATUS_NORMAL) {
2543 connection->status = Connection::STATUS_BROKEN;
2544
2545 if (notify) {
2546 // Notify other system components.
2547 onDispatchCycleBrokenLocked(currentTime, connection);
2548 }
2549 }
2550}
2551
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002552void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2553 while (!queue.empty()) {
2554 DispatchEntry* dispatchEntry = queue.front();
2555 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002556 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002557 }
2558}
2559
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002560void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002561 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002562 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002563 }
2564 delete dispatchEntry;
2565}
2566
2567int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2568 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2569
2570 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002571 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002572
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002573 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002574 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002575 "fd=%d, events=0x%x",
2576 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002577 return 0; // remove the callback
2578 }
2579
2580 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002581 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002582 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2583 if (!(events & ALOOPER_EVENT_INPUT)) {
2584 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002585 "events=0x%x",
2586 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002587 return 1;
2588 }
2589
2590 nsecs_t currentTime = now();
2591 bool gotOne = false;
2592 status_t status;
2593 for (;;) {
2594 uint32_t seq;
2595 bool handled;
2596 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2597 if (status) {
2598 break;
2599 }
2600 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2601 gotOne = true;
2602 }
2603 if (gotOne) {
2604 d->runCommandsLockedInterruptible();
2605 if (status == WOULD_BLOCK) {
2606 return 1;
2607 }
2608 }
2609
2610 notify = status != DEAD_OBJECT || !connection->monitor;
2611 if (notify) {
2612 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002613 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002614 }
2615 } else {
2616 // Monitor channels are never explicitly unregistered.
2617 // We do it automatically when the remote endpoint is closed so don't warn
2618 // about them.
2619 notify = !connection->monitor;
2620 if (notify) {
2621 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002622 "events=0x%x",
2623 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002624 }
2625 }
2626
2627 // Unregister the channel.
2628 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2629 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002630 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08002631}
2632
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002633void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002634 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002635 for (const auto& pair : mConnectionsByFd) {
2636 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002637 }
2638}
2639
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002640void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002641 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002642 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2643 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2644}
2645
2646void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2647 const CancelationOptions& options,
2648 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2649 for (const auto& it : monitorsByDisplay) {
2650 const std::vector<Monitor>& monitors = it.second;
2651 for (const Monitor& monitor : monitors) {
2652 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002653 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002654 }
2655}
2656
Michael Wrightd02c5b62014-02-10 15:10:22 -08002657void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2658 const sp<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002659 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002660 if (connection == nullptr) {
2661 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002662 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002663
2664 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002665}
2666
2667void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2668 const sp<Connection>& connection, const CancelationOptions& options) {
2669 if (connection->status == Connection::STATUS_BROKEN) {
2670 return;
2671 }
2672
2673 nsecs_t currentTime = now();
2674
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07002675 std::vector<EventEntry*> cancelationEvents =
2676 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002677
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002678 if (!cancelationEvents.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002679#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002680 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002681 "with reality: %s, mode=%d.",
2682 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
2683 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002684#endif
2685 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002686 EventEntry* cancelationEventEntry = cancelationEvents[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002687 switch (cancelationEventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002688 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002689 logOutboundKeyDetails("cancel - ",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002690 static_cast<const KeyEntry&>(*cancelationEventEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002691 break;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002692 }
2693 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002694 logOutboundMotionDetails("cancel - ",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002695 static_cast<const MotionEntry&>(
2696 *cancelationEventEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002697 break;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002698 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002699 case EventEntry::Type::FOCUS: {
2700 LOG_ALWAYS_FATAL("Canceling focus events is not supported");
2701 break;
2702 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002703 case EventEntry::Type::CONFIGURATION_CHANGED:
2704 case EventEntry::Type::DEVICE_RESET: {
2705 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2706 EventEntry::typeToString(cancelationEventEntry->type));
2707 break;
2708 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002709 }
2710
2711 InputTarget target;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002712 sp<InputWindowHandle> windowHandle =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002713 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07002714 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002715 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002716 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2717 windowInfo->windowXScale, windowInfo->windowYScale);
Robert Carre07e1032018-11-26 12:55:53 -08002718 target.globalScaleFactor = windowInfo->globalScaleFactor;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002719 }
2720 target.inputChannel = connection->inputChannel;
2721 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2722
chaviw8c9cf542019-03-25 13:02:48 -07002723 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002724 target, InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002725
2726 cancelationEventEntry->release();
2727 }
2728
2729 startDispatchCycleLocked(currentTime, connection);
2730 }
2731}
2732
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002733MotionEntry* InputDispatcher::splitMotionEvent(const MotionEntry& originalMotionEntry,
Garfield Tane84e6f92019-08-29 17:28:41 -07002734 BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002735 ALOG_ASSERT(pointerIds.value != 0);
2736
2737 uint32_t splitPointerIndexMap[MAX_POINTERS];
2738 PointerProperties splitPointerProperties[MAX_POINTERS];
2739 PointerCoords splitPointerCoords[MAX_POINTERS];
2740
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002741 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002742 uint32_t splitPointerCount = 0;
2743
2744 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002745 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002746 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002747 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002748 uint32_t pointerId = uint32_t(pointerProperties.id);
2749 if (pointerIds.hasBit(pointerId)) {
2750 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2751 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2752 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002753 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002754 splitPointerCount += 1;
2755 }
2756 }
2757
2758 if (splitPointerCount != pointerIds.count()) {
2759 // This is bad. We are missing some of the pointers that we expected to deliver.
2760 // Most likely this indicates that we received an ACTION_MOVE events that has
2761 // different pointer ids than we expected based on the previous ACTION_DOWN
2762 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2763 // in this way.
2764 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002765 "we expected there to be %d pointers. This probably means we received "
2766 "a broken sequence of pointer ids from the input device.",
2767 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002768 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002769 }
2770
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002771 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002772 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002773 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
2774 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002775 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2776 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002777 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002778 uint32_t pointerId = uint32_t(pointerProperties.id);
2779 if (pointerIds.hasBit(pointerId)) {
2780 if (pointerIds.count() == 1) {
2781 // The first/last pointer went down/up.
2782 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002783 ? AMOTION_EVENT_ACTION_DOWN
2784 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002785 } else {
2786 // A secondary pointer went down/up.
2787 uint32_t splitPointerIndex = 0;
2788 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2789 splitPointerIndex += 1;
2790 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002791 action = maskedAction |
2792 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002793 }
2794 } else {
2795 // An unrelated pointer changed.
2796 action = AMOTION_EVENT_ACTION_MOVE;
2797 }
2798 }
2799
Garfield Tan00f511d2019-06-12 16:55:40 -07002800 MotionEntry* splitMotionEntry =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002801 new MotionEntry(originalMotionEntry.sequenceNum, originalMotionEntry.eventTime,
2802 originalMotionEntry.deviceId, originalMotionEntry.source,
2803 originalMotionEntry.displayId, originalMotionEntry.policyFlags, action,
2804 originalMotionEntry.actionButton, originalMotionEntry.flags,
2805 originalMotionEntry.metaState, originalMotionEntry.buttonState,
2806 originalMotionEntry.classification, originalMotionEntry.edgeFlags,
2807 originalMotionEntry.xPrecision, originalMotionEntry.yPrecision,
2808 originalMotionEntry.xCursorPosition,
2809 originalMotionEntry.yCursorPosition, originalMotionEntry.downTime,
Garfield Tan00f511d2019-06-12 16:55:40 -07002810 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002811
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002812 if (originalMotionEntry.injectionState) {
2813 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002814 splitMotionEntry->injectionState->refCount += 1;
2815 }
2816
2817 return splitMotionEntry;
2818}
2819
2820void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2821#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002822 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002823#endif
2824
2825 bool needWake;
2826 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002827 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002828
Prabir Pradhan42611e02018-11-27 14:04:02 -08002829 ConfigurationChangedEntry* newEntry =
2830 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002831 needWake = enqueueInboundEventLocked(newEntry);
2832 } // release lock
2833
2834 if (needWake) {
2835 mLooper->wake();
2836 }
2837}
2838
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002839/**
2840 * If one of the meta shortcuts is detected, process them here:
2841 * Meta + Backspace -> generate BACK
2842 * Meta + Enter -> generate HOME
2843 * This will potentially overwrite keyCode and metaState.
2844 */
2845void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002846 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002847 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2848 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2849 if (keyCode == AKEYCODE_DEL) {
2850 newKeyCode = AKEYCODE_BACK;
2851 } else if (keyCode == AKEYCODE_ENTER) {
2852 newKeyCode = AKEYCODE_HOME;
2853 }
2854 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002855 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002856 struct KeyReplacement replacement = {keyCode, deviceId};
2857 mReplacedKeys.add(replacement, newKeyCode);
2858 keyCode = newKeyCode;
2859 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2860 }
2861 } else if (action == AKEY_EVENT_ACTION_UP) {
2862 // In order to maintain a consistent stream of up and down events, check to see if the key
2863 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2864 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002865 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002866 struct KeyReplacement replacement = {keyCode, deviceId};
2867 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2868 if (index >= 0) {
2869 keyCode = mReplacedKeys.valueAt(index);
2870 mReplacedKeys.removeItemsAt(index);
2871 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2872 }
2873 }
2874}
2875
Michael Wrightd02c5b62014-02-10 15:10:22 -08002876void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2877#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002878 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
2879 "policyFlags=0x%x, action=0x%x, "
2880 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
2881 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2882 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
2883 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002884#endif
2885 if (!validateKeyEvent(args->action)) {
2886 return;
2887 }
2888
2889 uint32_t policyFlags = args->policyFlags;
2890 int32_t flags = args->flags;
2891 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002892 // InputDispatcher tracks and generates key repeats on behalf of
2893 // whatever notifies it, so repeatCount should always be set to 0
2894 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002895 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2896 policyFlags |= POLICY_FLAG_VIRTUAL;
2897 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2898 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002899 if (policyFlags & POLICY_FLAG_FUNCTION) {
2900 metaState |= AMETA_FUNCTION_ON;
2901 }
2902
2903 policyFlags |= POLICY_FLAG_TRUSTED;
2904
Michael Wright78f24442014-08-06 15:55:28 -07002905 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002906 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002907
Michael Wrightd02c5b62014-02-10 15:10:22 -08002908 KeyEvent event;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002909 event.initialize(args->deviceId, args->source, args->displayId, args->action, flags, keyCode,
2910 args->scanCode, metaState, repeatCount, args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002911
Michael Wright2b3c3302018-03-02 17:19:13 +00002912 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002913 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002914 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2915 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002916 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00002917 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002918
Michael Wrightd02c5b62014-02-10 15:10:22 -08002919 bool needWake;
2920 { // acquire lock
2921 mLock.lock();
2922
2923 if (shouldSendKeyToInputFilterLocked(args)) {
2924 mLock.unlock();
2925
2926 policyFlags |= POLICY_FLAG_FILTERED;
2927 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2928 return; // event was consumed by the filter
2929 }
2930
2931 mLock.lock();
2932 }
2933
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002934 KeyEntry* newEntry =
2935 new KeyEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2936 args->displayId, policyFlags, args->action, flags, keyCode,
2937 args->scanCode, metaState, repeatCount, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002938
2939 needWake = enqueueInboundEventLocked(newEntry);
2940 mLock.unlock();
2941 } // release lock
2942
2943 if (needWake) {
2944 mLooper->wake();
2945 }
2946}
2947
2948bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2949 return mInputFilterEnabled;
2950}
2951
2952void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2953#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002954 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07002955 ", policyFlags=0x%x, "
2956 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
2957 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07002958 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07002959 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2960 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
Jaewan Kim372fbe42019-10-02 10:58:46 +09002961 args->edgeFlags, args->xPrecision, args->yPrecision, args->xCursorPosition,
Garfield Tan00f511d2019-06-12 16:55:40 -07002962 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002963 for (uint32_t i = 0; i < args->pointerCount; i++) {
2964 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002965 "x=%f, y=%f, pressure=%f, size=%f, "
2966 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2967 "orientation=%f",
2968 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
2969 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2970 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2971 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2972 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2973 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2974 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2975 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2976 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2977 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002978 }
2979#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002980 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
2981 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002982 return;
2983 }
2984
2985 uint32_t policyFlags = args->policyFlags;
2986 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00002987
2988 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002989 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002990 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2991 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002992 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00002993 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002994
2995 bool needWake;
2996 { // acquire lock
2997 mLock.lock();
2998
2999 if (shouldSendMotionToInputFilterLocked(args)) {
3000 mLock.unlock();
3001
3002 MotionEvent event;
Garfield Tan00f511d2019-06-12 16:55:40 -07003003 event.initialize(args->deviceId, args->source, args->displayId, args->action,
3004 args->actionButton, args->flags, args->edgeFlags, args->metaState,
3005 args->buttonState, args->classification, 0, 0, args->xPrecision,
3006 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3007 args->downTime, args->eventTime, args->pointerCount,
3008 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003009
3010 policyFlags |= POLICY_FLAG_FILTERED;
3011 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3012 return; // event was consumed by the filter
3013 }
3014
3015 mLock.lock();
3016 }
3017
3018 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07003019 MotionEntry* newEntry =
3020 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
3021 args->displayId, policyFlags, args->action, args->actionButton,
3022 args->flags, args->metaState, args->buttonState,
3023 args->classification, args->edgeFlags, args->xPrecision,
3024 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3025 args->downTime, args->pointerCount, args->pointerProperties,
3026 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003027
3028 needWake = enqueueInboundEventLocked(newEntry);
3029 mLock.unlock();
3030 } // release lock
3031
3032 if (needWake) {
3033 mLooper->wake();
3034 }
3035}
3036
3037bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003038 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003039}
3040
3041void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3042#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003043 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003044 "switchMask=0x%08x",
3045 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003046#endif
3047
3048 uint32_t policyFlags = args->policyFlags;
3049 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003050 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003051}
3052
3053void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3054#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003055 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3056 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003057#endif
3058
3059 bool needWake;
3060 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003061 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003062
Prabir Pradhan42611e02018-11-27 14:04:02 -08003063 DeviceResetEntry* newEntry =
3064 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003065 needWake = enqueueInboundEventLocked(newEntry);
3066 } // release lock
3067
3068 if (needWake) {
3069 mLooper->wake();
3070 }
3071}
3072
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003073int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid,
3074 int32_t injectorUid, int32_t syncMode,
3075 int32_t timeoutMillis, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003076#if DEBUG_INBOUND_EVENT_DETAILS
3077 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003078 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
3079 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003080#endif
3081
3082 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
3083
3084 policyFlags |= POLICY_FLAG_INJECTED;
3085 if (hasInjectionPermission(injectorPid, injectorUid)) {
3086 policyFlags |= POLICY_FLAG_TRUSTED;
3087 }
3088
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003089 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003090 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003091 case AINPUT_EVENT_TYPE_KEY: {
3092 KeyEvent keyEvent;
3093 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
3094 int32_t action = keyEvent.getAction();
3095 if (!validateKeyEvent(action)) {
3096 return INPUT_EVENT_INJECTION_FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003097 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003098
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003099 int32_t flags = keyEvent.getFlags();
3100 int32_t keyCode = keyEvent.getKeyCode();
3101 int32_t metaState = keyEvent.getMetaState();
3102 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
3103 /*byref*/ keyCode, /*byref*/ metaState);
3104 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(),
3105 keyEvent.getDisplayId(), action, flags, keyCode,
3106 keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
3107 keyEvent.getDownTime(), keyEvent.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003108
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003109 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3110 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003111 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003112
3113 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3114 android::base::Timer t;
3115 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3116 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3117 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3118 std::to_string(t.duration().count()).c_str());
3119 }
3120 }
3121
3122 mLock.lock();
3123 KeyEntry* injectedEntry =
3124 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
3125 keyEvent.getDeviceId(), keyEvent.getSource(),
3126 keyEvent.getDisplayId(), policyFlags, action, flags,
3127 keyEvent.getKeyCode(), keyEvent.getScanCode(),
3128 keyEvent.getMetaState(), keyEvent.getRepeatCount(),
3129 keyEvent.getDownTime());
3130 injectedEntries.push(injectedEntry);
3131 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003132 }
3133
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003134 case AINPUT_EVENT_TYPE_MOTION: {
3135 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3136 int32_t action = motionEvent->getAction();
3137 size_t pointerCount = motionEvent->getPointerCount();
3138 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3139 int32_t actionButton = motionEvent->getActionButton();
3140 int32_t displayId = motionEvent->getDisplayId();
3141 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
3142 return INPUT_EVENT_INJECTION_FAILED;
3143 }
3144
3145 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3146 nsecs_t eventTime = motionEvent->getEventTime();
3147 android::base::Timer t;
3148 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3149 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3150 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3151 std::to_string(t.duration().count()).c_str());
3152 }
3153 }
3154
3155 mLock.lock();
3156 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3157 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
3158 MotionEntry* injectedEntry =
Garfield Tan00f511d2019-06-12 16:55:40 -07003159 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3160 motionEvent->getDeviceId(), motionEvent->getSource(),
3161 motionEvent->getDisplayId(), policyFlags, action, actionButton,
3162 motionEvent->getFlags(), motionEvent->getMetaState(),
3163 motionEvent->getButtonState(), motionEvent->getClassification(),
3164 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3165 motionEvent->getYPrecision(),
3166 motionEvent->getRawXCursorPosition(),
3167 motionEvent->getRawYCursorPosition(),
3168 motionEvent->getDownTime(), uint32_t(pointerCount),
3169 pointerProperties, samplePointerCoords,
3170 motionEvent->getXOffset(), motionEvent->getYOffset());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003171 injectedEntries.push(injectedEntry);
3172 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3173 sampleEventTimes += 1;
3174 samplePointerCoords += pointerCount;
3175 MotionEntry* nextInjectedEntry =
3176 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3177 motionEvent->getDeviceId(), motionEvent->getSource(),
3178 motionEvent->getDisplayId(), policyFlags, action,
3179 actionButton, motionEvent->getFlags(),
3180 motionEvent->getMetaState(), motionEvent->getButtonState(),
3181 motionEvent->getClassification(),
3182 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3183 motionEvent->getYPrecision(),
3184 motionEvent->getRawXCursorPosition(),
3185 motionEvent->getRawYCursorPosition(),
3186 motionEvent->getDownTime(), uint32_t(pointerCount),
3187 pointerProperties, samplePointerCoords,
3188 motionEvent->getXOffset(), motionEvent->getYOffset());
3189 injectedEntries.push(nextInjectedEntry);
3190 }
3191 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003192 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003193
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003194 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003195 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003196 return INPUT_EVENT_INJECTION_FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003197 }
3198
3199 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3200 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3201 injectionState->injectionIsAsync = true;
3202 }
3203
3204 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003205 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003206
3207 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003208 while (!injectedEntries.empty()) {
3209 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3210 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003211 }
3212
3213 mLock.unlock();
3214
3215 if (needWake) {
3216 mLooper->wake();
3217 }
3218
3219 int32_t injectionResult;
3220 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003221 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003222
3223 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3224 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3225 } else {
3226 for (;;) {
3227 injectionResult = injectionState->injectionResult;
3228 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3229 break;
3230 }
3231
3232 nsecs_t remainingTimeout = endTime - now();
3233 if (remainingTimeout <= 0) {
3234#if DEBUG_INJECTION
3235 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003236 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003237#endif
3238 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3239 break;
3240 }
3241
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003242 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003243 }
3244
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003245 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED &&
3246 syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003247 while (injectionState->pendingForegroundDispatches != 0) {
3248#if DEBUG_INJECTION
3249 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003250 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003251#endif
3252 nsecs_t remainingTimeout = endTime - now();
3253 if (remainingTimeout <= 0) {
3254#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003255 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3256 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003257#endif
3258 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3259 break;
3260 }
3261
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003262 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003263 }
3264 }
3265 }
3266
3267 injectionState->release();
3268 } // release lock
3269
3270#if DEBUG_INJECTION
3271 ALOGD("injectInputEvent - Finished with result %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003272 "injectorPid=%d, injectorUid=%d",
3273 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003274#endif
3275
3276 return injectionResult;
3277}
3278
3279bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003280 return injectorUid == 0 ||
3281 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003282}
3283
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003284void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003285 InjectionState* injectionState = entry->injectionState;
3286 if (injectionState) {
3287#if DEBUG_INJECTION
3288 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003289 "injectorPid=%d, injectorUid=%d",
3290 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003291#endif
3292
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003293 if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003294 // Log the outcome since the injector did not wait for the injection result.
3295 switch (injectionResult) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003296 case INPUT_EVENT_INJECTION_SUCCEEDED:
3297 ALOGV("Asynchronous input event injection succeeded.");
3298 break;
3299 case INPUT_EVENT_INJECTION_FAILED:
3300 ALOGW("Asynchronous input event injection failed.");
3301 break;
3302 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3303 ALOGW("Asynchronous input event injection permission denied.");
3304 break;
3305 case INPUT_EVENT_INJECTION_TIMED_OUT:
3306 ALOGW("Asynchronous input event injection timed out.");
3307 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003308 }
3309 }
3310
3311 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003312 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003313 }
3314}
3315
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003316void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003317 InjectionState* injectionState = entry->injectionState;
3318 if (injectionState) {
3319 injectionState->pendingForegroundDispatches += 1;
3320 }
3321}
3322
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003323void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003324 InjectionState* injectionState = entry->injectionState;
3325 if (injectionState) {
3326 injectionState->pendingForegroundDispatches -= 1;
3327
3328 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003329 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003330 }
3331 }
3332}
3333
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003334std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3335 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003336 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003337}
3338
Michael Wrightd02c5b62014-02-10 15:10:22 -08003339sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003340 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003341 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003342 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3343 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003344 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003345 return windowHandle;
3346 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003347 }
3348 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003349 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003350}
3351
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003352bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003353 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003354 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3355 for (const sp<InputWindowHandle>& handle : windowHandles) {
3356 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003357 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003358 ALOGE("Found window %s in display %" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003359 ", but it should belong to display %" PRId32,
3360 windowHandle->getName().c_str(), it.first,
3361 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003362 }
3363 return true;
3364 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003365 }
3366 }
3367 return false;
3368}
3369
Robert Carr5c8a0262018-10-03 16:30:44 -07003370sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3371 size_t count = mInputChannelsByToken.count(token);
3372 if (count == 0) {
3373 return nullptr;
3374 }
3375 return mInputChannelsByToken.at(token);
3376}
3377
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003378void InputDispatcher::updateWindowHandlesForDisplayLocked(
3379 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3380 if (inputWindowHandles.empty()) {
3381 // Remove all handles on a display if there are no windows left.
3382 mWindowHandlesByDisplay.erase(displayId);
3383 return;
3384 }
3385
3386 // Since we compare the pointer of input window handles across window updates, we need
3387 // to make sure the handle object for the same window stays unchanged across updates.
3388 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003389 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003390 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003391 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003392 }
3393
3394 std::vector<sp<InputWindowHandle>> newHandles;
3395 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3396 if (!handle->updateInfo()) {
3397 // handle no longer valid
3398 continue;
3399 }
3400
3401 const InputWindowInfo* info = handle->getInfo();
3402 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3403 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3404 const bool noInputChannel =
3405 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3406 const bool canReceiveInput =
3407 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3408 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3409 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003410 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003411 handle->getName().c_str());
3412 }
3413 continue;
3414 }
3415
3416 if (info->displayId != displayId) {
3417 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3418 handle->getName().c_str(), displayId, info->displayId);
3419 continue;
3420 }
3421
chaviwaf87b3e2019-10-01 16:59:28 -07003422 if (oldHandlesById.find(handle->getId()) != oldHandlesById.end()) {
3423 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003424 oldHandle->updateFrom(handle);
3425 newHandles.push_back(oldHandle);
3426 } else {
3427 newHandles.push_back(handle);
3428 }
3429 }
3430
3431 // Insert or replace
3432 mWindowHandlesByDisplay[displayId] = newHandles;
3433}
3434
Arthur Hungb92218b2018-08-14 12:00:21 +08003435/**
3436 * Called from InputManagerService, update window handle list by displayId that can receive input.
3437 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3438 * If set an empty list, remove all handles from the specific display.
3439 * For focused handle, check if need to change and send a cancel event to previous one.
3440 * For removed handle, check if need to send a cancel event if already in touch.
3441 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003442void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003443 int32_t displayId,
3444 const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003445 if (DEBUG_FOCUS) {
3446 std::string windowList;
3447 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
3448 windowList += iwh->getName() + " ";
3449 }
3450 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
3451 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003452 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003453 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003454
Arthur Hungb92218b2018-08-14 12:00:21 +08003455 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003456 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3457 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003458
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003459 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3460
Tiger Huang721e26f2018-07-24 22:26:19 +08003461 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003462 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003463 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3464 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3465 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3466 windowHandle->getInfo()->visible) {
3467 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003468 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003469 if (windowHandle == mLastHoverWindowHandle) {
3470 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003471 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003472 }
3473
3474 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003475 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003476 }
3477
Tiger Huang721e26f2018-07-24 22:26:19 +08003478 sp<InputWindowHandle> oldFocusedWindowHandle =
3479 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3480
chaviwaf87b3e2019-10-01 16:59:28 -07003481 if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003482 if (oldFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003483 if (DEBUG_FOCUS) {
3484 ALOGD("Focus left window: %s in display %" PRId32,
3485 oldFocusedWindowHandle->getName().c_str(), displayId);
3486 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003487 sp<InputChannel> focusedInputChannel =
3488 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003489 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003490 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003491 "focus left window");
3492 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003493 enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003494 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003495 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003496 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003497 if (newFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003498 if (DEBUG_FOCUS) {
3499 ALOGD("Focus entered window: %s in display %" PRId32,
3500 newFocusedWindowHandle->getName().c_str(), displayId);
3501 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003502 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003503 enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003504 }
Robert Carrf759f162018-11-13 12:57:11 -08003505
3506 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003507 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003508 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003509 }
3510
Arthur Hungb92218b2018-08-14 12:00:21 +08003511 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3512 if (stateIndex >= 0) {
3513 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003514 for (size_t i = 0; i < state.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003515 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003516 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003517 if (DEBUG_FOCUS) {
3518 ALOGD("Touched window was removed: %s in display %" PRId32,
3519 touchedWindow.windowHandle->getName().c_str(), displayId);
3520 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003521 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003522 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003523 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003524 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003525 "touched window was removed");
3526 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
3527 options);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003528 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003529 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003530 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003531 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003532 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003533 }
3534 }
3535
3536 // Release information for windows that are no longer present.
3537 // This ensures that unused input channels are released promptly.
3538 // Otherwise, they might stick around until the window handle is destroyed
3539 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003540 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003541 if (!hasWindowHandleLocked(oldWindowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003542 if (DEBUG_FOCUS) {
3543 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
3544 }
Arthur Hung3b413f22018-10-26 18:05:34 +08003545 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003546 }
3547 }
3548 } // release lock
3549
3550 // Wake up poll loop since it may need to make new input dispatching choices.
3551 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003552
3553 if (setInputWindowsListener) {
3554 setInputWindowsListener->onSetInputWindowsFinished();
3555 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003556}
3557
3558void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003559 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003560 if (DEBUG_FOCUS) {
3561 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
3562 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
3563 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003564 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003565 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003566
Tiger Huang721e26f2018-07-24 22:26:19 +08003567 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3568 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003569 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003570 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3571 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003572 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003573 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003574 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003575 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003576 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003577 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003578 oldFocusedApplicationHandle.clear();
3579 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003580 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003581 } // release lock
3582
3583 // Wake up poll loop since it may need to make new input dispatching choices.
3584 mLooper->wake();
3585}
3586
Tiger Huang721e26f2018-07-24 22:26:19 +08003587/**
3588 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3589 * the display not specified.
3590 *
3591 * We track any unreleased events for each window. If a window loses the ability to receive the
3592 * released event, we will send a cancel event to it. So when the focused display is changed, we
3593 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3594 * display. The display-specified events won't be affected.
3595 */
3596void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003597 if (DEBUG_FOCUS) {
3598 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3599 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003600 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003601 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003602
3603 if (mFocusedDisplayId != displayId) {
3604 sp<InputWindowHandle> oldFocusedWindowHandle =
3605 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3606 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003607 sp<InputChannel> inputChannel =
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003608 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003609 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003610 CancelationOptions
3611 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3612 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003613 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003614 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3615 }
3616 }
3617 mFocusedDisplayId = displayId;
3618
3619 // Sanity check
3620 sp<InputWindowHandle> newFocusedWindowHandle =
3621 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003622 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003623
Tiger Huang721e26f2018-07-24 22:26:19 +08003624 if (newFocusedWindowHandle == nullptr) {
3625 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3626 if (!mFocusedWindowHandlesByDisplay.empty()) {
3627 ALOGE("But another display has a focused window:");
3628 for (auto& it : mFocusedWindowHandlesByDisplay) {
3629 const int32_t displayId = it.first;
3630 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003631 ALOGE("Display #%" PRId32 " has focused window: '%s'\n", displayId,
3632 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003633 }
3634 }
3635 }
3636 }
3637
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003638 if (DEBUG_FOCUS) {
3639 logDispatchStateLocked();
3640 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003641 } // release lock
3642
3643 // Wake up poll loop since it may need to make new input dispatching choices.
3644 mLooper->wake();
3645}
3646
Michael Wrightd02c5b62014-02-10 15:10:22 -08003647void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003648 if (DEBUG_FOCUS) {
3649 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3650 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003651
3652 bool changed;
3653 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003654 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003655
3656 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3657 if (mDispatchFrozen && !frozen) {
3658 resetANRTimeoutsLocked();
3659 }
3660
3661 if (mDispatchEnabled && !enabled) {
3662 resetAndDropEverythingLocked("dispatcher is being disabled");
3663 }
3664
3665 mDispatchEnabled = enabled;
3666 mDispatchFrozen = frozen;
3667 changed = true;
3668 } else {
3669 changed = false;
3670 }
3671
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003672 if (DEBUG_FOCUS) {
3673 logDispatchStateLocked();
3674 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003675 } // release lock
3676
3677 if (changed) {
3678 // Wake up poll loop since it may need to make new input dispatching choices.
3679 mLooper->wake();
3680 }
3681}
3682
3683void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003684 if (DEBUG_FOCUS) {
3685 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3686 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003687
3688 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003689 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003690
3691 if (mInputFilterEnabled == enabled) {
3692 return;
3693 }
3694
3695 mInputFilterEnabled = enabled;
3696 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3697 } // release lock
3698
3699 // Wake up poll loop since there might be work to do to drop everything.
3700 mLooper->wake();
3701}
3702
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08003703void InputDispatcher::setInTouchMode(bool inTouchMode) {
3704 std::scoped_lock lock(mLock);
3705 mInTouchMode = inTouchMode;
3706}
3707
chaviwfbe5d9c2018-12-26 12:23:37 -08003708bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3709 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003710 if (DEBUG_FOCUS) {
3711 ALOGD("Trivial transfer to same window.");
3712 }
chaviwfbe5d9c2018-12-26 12:23:37 -08003713 return true;
3714 }
3715
Michael Wrightd02c5b62014-02-10 15:10:22 -08003716 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003717 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003718
chaviwfbe5d9c2018-12-26 12:23:37 -08003719 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3720 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003721 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003722 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003723 return false;
3724 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003725 if (DEBUG_FOCUS) {
3726 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3727 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3728 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003729 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003730 if (DEBUG_FOCUS) {
3731 ALOGD("Cannot transfer focus because windows are on different displays.");
3732 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003733 return false;
3734 }
3735
3736 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003737 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3738 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3739 for (size_t i = 0; i < state.windows.size(); i++) {
3740 const TouchedWindow& touchedWindow = state.windows[i];
3741 if (touchedWindow.windowHandle == fromWindowHandle) {
3742 int32_t oldTargetFlags = touchedWindow.targetFlags;
3743 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003744
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003745 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003746
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003747 int32_t newTargetFlags = oldTargetFlags &
3748 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
3749 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003750 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003751
Jeff Brownf086ddb2014-02-11 14:28:48 -08003752 found = true;
3753 goto Found;
3754 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003755 }
3756 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003757 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003758
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003759 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003760 if (DEBUG_FOCUS) {
3761 ALOGD("Focus transfer failed because from window did not have focus.");
3762 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003763 return false;
3764 }
3765
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07003766 sp<Connection> fromConnection = getConnectionLocked(fromToken);
3767 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003768 if (fromConnection != nullptr && toConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003769 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003770 CancelationOptions
3771 options(CancelationOptions::CANCEL_POINTER_EVENTS,
3772 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003773 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
3774 }
3775
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003776 if (DEBUG_FOCUS) {
3777 logDispatchStateLocked();
3778 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003779 } // release lock
3780
3781 // Wake up poll loop since it may need to make new input dispatching choices.
3782 mLooper->wake();
3783 return true;
3784}
3785
3786void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003787 if (DEBUG_FOCUS) {
3788 ALOGD("Resetting and dropping all events (%s).", reason);
3789 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003790
3791 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3792 synthesizeCancelationEventsForAllConnectionsLocked(options);
3793
3794 resetKeyRepeatLocked();
3795 releasePendingEventLocked();
3796 drainInboundQueueLocked();
3797 resetANRTimeoutsLocked();
3798
Jeff Brownf086ddb2014-02-11 14:28:48 -08003799 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003800 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003801 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003802}
3803
3804void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003805 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003806 dumpDispatchStateLocked(dump);
3807
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003808 std::istringstream stream(dump);
3809 std::string line;
3810
3811 while (std::getline(stream, line, '\n')) {
3812 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003813 }
3814}
3815
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003816void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003817 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3818 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3819 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003820 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003821
Tiger Huang721e26f2018-07-24 22:26:19 +08003822 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3823 dump += StringPrintf(INDENT "FocusedApplications:\n");
3824 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3825 const int32_t displayId = it.first;
3826 const sp<InputApplicationHandle>& applicationHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003827 dump += StringPrintf(INDENT2 "displayId=%" PRId32
3828 ", name='%s', dispatchingTimeout=%0.3fms\n",
3829 displayId, applicationHandle->getName().c_str(),
3830 applicationHandle->getDispatchingTimeout(
3831 DEFAULT_INPUT_DISPATCHING_TIMEOUT) /
3832 1000000.0);
Tiger Huang721e26f2018-07-24 22:26:19 +08003833 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003834 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003835 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003836 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003837
3838 if (!mFocusedWindowHandlesByDisplay.empty()) {
3839 dump += StringPrintf(INDENT "FocusedWindows:\n");
3840 for (auto& it : mFocusedWindowHandlesByDisplay) {
3841 const int32_t displayId = it.first;
3842 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003843 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
3844 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003845 }
3846 } else {
3847 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3848 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003849
Jeff Brownf086ddb2014-02-11 14:28:48 -08003850 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003851 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003852 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3853 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003854 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003855 state.displayId, toString(state.down), toString(state.split),
3856 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003857 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003858 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003859 for (size_t i = 0; i < state.windows.size(); i++) {
3860 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003861 dump += StringPrintf(INDENT4
3862 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3863 i, touchedWindow.windowHandle->getName().c_str(),
3864 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003865 }
3866 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003867 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003868 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003869 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003870 dump += INDENT3 "Portal windows:\n";
3871 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003872 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003873 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
3874 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003875 }
3876 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003877 }
3878 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003879 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003880 }
3881
Arthur Hungb92218b2018-08-14 12:00:21 +08003882 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003883 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003884 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003885 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003886 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003887 dump += INDENT2 "Windows:\n";
3888 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003889 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003890 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003891
Arthur Hungb92218b2018-08-14 12:00:21 +08003892 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003893 "portalToDisplayId=%d, paused=%s, hasFocus=%s, "
chaviwcb923212019-12-30 14:05:11 -08003894 "hasWallpaper=%s, visible=%s, canReceiveKeys=%s, "
3895 "flags=0x%08x, type=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003896 "frame=[%d,%d][%d,%d], globalScale=%f, "
chaviwcb923212019-12-30 14:05:11 -08003897 "windowScale=(%f,%f), touchableRegion=",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003898 i, windowInfo->name.c_str(), windowInfo->displayId,
3899 windowInfo->portalToDisplayId,
3900 toString(windowInfo->paused),
3901 toString(windowInfo->hasFocus),
3902 toString(windowInfo->hasWallpaper),
3903 toString(windowInfo->visible),
3904 toString(windowInfo->canReceiveKeys),
3905 windowInfo->layoutParamsFlags,
chaviwcb923212019-12-30 14:05:11 -08003906 windowInfo->layoutParamsType, windowInfo->frameLeft,
3907 windowInfo->frameTop, windowInfo->frameRight,
3908 windowInfo->frameBottom, windowInfo->globalScaleFactor,
3909 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003910 dumpRegion(dump, windowInfo->touchableRegion);
3911 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3912 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003913 windowInfo->ownerPid, windowInfo->ownerUid,
3914 windowInfo->dispatchingTimeout / 1000000.0);
Arthur Hungb92218b2018-08-14 12:00:21 +08003915 }
3916 } else {
3917 dump += INDENT2 "Windows: <none>\n";
3918 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003919 }
3920 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003921 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003922 }
3923
Michael Wright3dd60e22019-03-27 22:06:44 +00003924 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003925 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003926 const std::vector<Monitor>& monitors = it.second;
3927 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3928 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003929 }
3930 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003931 const std::vector<Monitor>& monitors = it.second;
3932 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
3933 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003934 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003935 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00003936 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003937 }
3938
3939 nsecs_t currentTime = now();
3940
3941 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003942 if (!mRecentQueue.empty()) {
3943 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
3944 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003945 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003946 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003947 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003948 }
3949 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003950 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003951 }
3952
3953 // Dump event currently being dispatched.
3954 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003955 dump += INDENT "PendingEvent:\n";
3956 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003957 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003958 dump += StringPrintf(", age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003959 (currentTime - mPendingEvent->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003960 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003961 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962 }
3963
3964 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003965 if (!mInboundQueue.empty()) {
3966 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
3967 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003968 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003969 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003970 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003971 }
3972 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003973 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003974 }
3975
Michael Wright78f24442014-08-06 15:55:28 -07003976 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003977 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07003978 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
3979 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
3980 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003981 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n", i,
3982 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07003983 }
3984 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003985 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07003986 }
3987
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003988 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003989 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003990 for (const auto& pair : mConnectionsByFd) {
3991 const sp<Connection>& connection = pair.second;
3992 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
3993 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
3994 pair.first, connection->getInputChannelName().c_str(),
3995 connection->getWindowName().c_str(), connection->getStatusLabel(),
3996 toString(connection->monitor),
3997 toString(connection->inputPublisherBlocked));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003998
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003999 if (!connection->outboundQueue.empty()) {
4000 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4001 connection->outboundQueue.size());
4002 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004003 dump.append(INDENT4);
4004 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004005 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004006 entry->targetFlags, entry->resolvedAction,
4007 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004008 }
4009 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004010 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004011 }
4012
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004013 if (!connection->waitQueue.empty()) {
4014 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4015 connection->waitQueue.size());
4016 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004017 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004018 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004019 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004020 "age=%0.1fms, wait=%0.1fms\n",
4021 entry->targetFlags, entry->resolvedAction,
4022 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
4023 (currentTime - entry->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004024 }
4025 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004026 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004027 }
4028 }
4029 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004030 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004031 }
4032
4033 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004034 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004035 (mAppSwitchDueTime - now()) / 1000000.0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004036 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004037 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004038 }
4039
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004040 dump += INDENT "Configuration:\n";
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004041 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004042 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004043 mConfig.keyRepeatTimeout * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004044}
4045
Michael Wright3dd60e22019-03-27 22:06:44 +00004046void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4047 const size_t numMonitors = monitors.size();
4048 for (size_t i = 0; i < numMonitors; i++) {
4049 const Monitor& monitor = monitors[i];
4050 const sp<InputChannel>& channel = monitor.inputChannel;
4051 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4052 dump += "\n";
4053 }
4054}
4055
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004056status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004057#if DEBUG_REGISTRATION
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004058 ALOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004059#endif
4060
4061 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004062 std::scoped_lock _l(mLock);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004063 sp<Connection> existingConnection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004064 if (existingConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004065 ALOGW("Attempted to register already registered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004066 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004067 return BAD_VALUE;
4068 }
4069
Michael Wright3dd60e22019-03-27 22:06:44 +00004070 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004071
4072 int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004073 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004074 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004075
Michael Wrightd02c5b62014-02-10 15:10:22 -08004076 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4077 } // release lock
4078
4079 // Wake the looper because some connections have changed.
4080 mLooper->wake();
4081 return OK;
4082}
4083
Michael Wright3dd60e22019-03-27 22:06:44 +00004084status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004085 int32_t displayId, bool isGestureMonitor) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004086 { // acquire lock
4087 std::scoped_lock _l(mLock);
4088
4089 if (displayId < 0) {
4090 ALOGW("Attempted to register input monitor without a specified display.");
4091 return BAD_VALUE;
4092 }
4093
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004094 if (inputChannel->getConnectionToken() == nullptr) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004095 ALOGW("Attempted to register input monitor without an identifying token.");
4096 return BAD_VALUE;
4097 }
4098
4099 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
4100
4101 const int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004102 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004103 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004104
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004105 auto& monitorsByDisplay =
4106 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Michael Wright3dd60e22019-03-27 22:06:44 +00004107 monitorsByDisplay[displayId].emplace_back(inputChannel);
4108
4109 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004110 }
4111 // Wake the looper because some connections have changed.
4112 mLooper->wake();
4113 return OK;
4114}
4115
Michael Wrightd02c5b62014-02-10 15:10:22 -08004116status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
4117#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004118 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004119#endif
4120
4121 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004122 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004123
4124 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
4125 if (status) {
4126 return status;
4127 }
4128 } // release lock
4129
4130 // Wake the poll loop because removing the connection may have changed the current
4131 // synchronization state.
4132 mLooper->wake();
4133 return OK;
4134}
4135
4136status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004137 bool notify) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004138 sp<Connection> connection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004139 if (connection == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004140 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004141 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004142 return BAD_VALUE;
4143 }
4144
John Recke0710582019-09-26 13:46:12 -07004145 [[maybe_unused]] const bool removed = removeByValue(mConnectionsByFd, connection);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004146 ALOG_ASSERT(removed);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004147 mInputChannelsByToken.erase(inputChannel->getConnectionToken());
Robert Carr5c8a0262018-10-03 16:30:44 -07004148
Michael Wrightd02c5b62014-02-10 15:10:22 -08004149 if (connection->monitor) {
4150 removeMonitorChannelLocked(inputChannel);
4151 }
4152
4153 mLooper->removeFd(inputChannel->getFd());
4154
4155 nsecs_t currentTime = now();
4156 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4157
4158 connection->status = Connection::STATUS_ZOMBIE;
4159 return OK;
4160}
4161
4162void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004163 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4164 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4165}
4166
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004167void InputDispatcher::removeMonitorChannelLocked(
4168 const sp<InputChannel>& inputChannel,
Michael Wright3dd60e22019-03-27 22:06:44 +00004169 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004170 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004171 std::vector<Monitor>& monitors = it->second;
4172 const size_t numMonitors = monitors.size();
4173 for (size_t i = 0; i < numMonitors; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004174 if (monitors[i].inputChannel == inputChannel) {
4175 monitors.erase(monitors.begin() + i);
4176 break;
4177 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004178 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004179 if (monitors.empty()) {
4180 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004181 } else {
4182 ++it;
4183 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004184 }
4185}
4186
Michael Wright3dd60e22019-03-27 22:06:44 +00004187status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4188 { // acquire lock
4189 std::scoped_lock _l(mLock);
4190 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4191
4192 if (!foundDisplayId) {
4193 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4194 return BAD_VALUE;
4195 }
4196 int32_t displayId = foundDisplayId.value();
4197
4198 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4199 if (stateIndex < 0) {
4200 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4201 return BAD_VALUE;
4202 }
4203
4204 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4205 std::optional<int32_t> foundDeviceId;
4206 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004207 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004208 foundDeviceId = state.deviceId;
4209 }
4210 }
4211 if (!foundDeviceId || !state.down) {
4212 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004213 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004214 return BAD_VALUE;
4215 }
4216 int32_t deviceId = foundDeviceId.value();
4217
4218 // Send cancel events to all the input channels we're stealing from.
4219 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004220 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004221 options.deviceId = deviceId;
4222 options.displayId = displayId;
4223 for (const TouchedWindow& window : state.windows) {
4224 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004225 if (channel != nullptr) {
4226 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4227 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004228 }
4229 // Then clear the current touch state so we stop dispatching to them as well.
4230 state.filterNonMonitors();
4231 }
4232 return OK;
4233}
4234
Michael Wright3dd60e22019-03-27 22:06:44 +00004235std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4236 const sp<IBinder>& token) {
4237 for (const auto& it : mGestureMonitorsByDisplay) {
4238 const std::vector<Monitor>& monitors = it.second;
4239 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004240 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004241 return it.first;
4242 }
4243 }
4244 }
4245 return std::nullopt;
4246}
4247
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004248sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) {
4249 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004250 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004251 }
4252
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004253 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004254 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004255 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004256 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004257 }
4258 }
Robert Carr4e670e52018-08-15 13:26:12 -07004259
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004260 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004261}
4262
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004263void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4264 const sp<Connection>& connection, uint32_t seq,
4265 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004266 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4267 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004268 commandEntry->connection = connection;
4269 commandEntry->eventTime = currentTime;
4270 commandEntry->seq = seq;
4271 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004272 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004273}
4274
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004275void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4276 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004277 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004278 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004279
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004280 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4281 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004282 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004283 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004284}
4285
chaviw0c06c6e2019-01-09 13:27:07 -08004286void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004287 const sp<InputWindowHandle>& newFocus) {
chaviw0c06c6e2019-01-09 13:27:07 -08004288 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4289 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004290 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4291 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004292 commandEntry->oldToken = oldToken;
4293 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004294 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004295}
4296
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004297void InputDispatcher::onANRLocked(nsecs_t currentTime,
4298 const sp<InputApplicationHandle>& applicationHandle,
4299 const sp<InputWindowHandle>& windowHandle, nsecs_t eventTime,
4300 nsecs_t waitStartTime, const char* reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004301 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4302 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4303 ALOGI("Application is not responding: %s. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004304 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
4305 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), dispatchLatency,
4306 waitDuration, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004307
4308 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004309 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004310 struct tm tm;
4311 localtime_r(&t, &tm);
4312 char timestr[64];
4313 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4314 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004315 mLastANRState += INDENT "ANR:\n";
4316 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004317 mLastANRState +=
4318 StringPrintf(INDENT2 "Window: %s\n",
4319 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004320 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4321 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4322 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004323 dumpDispatchStateLocked(mLastANRState);
4324
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004325 std::unique_ptr<CommandEntry> commandEntry =
4326 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004327 commandEntry->inputApplicationHandle = applicationHandle;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004328 commandEntry->inputChannel =
4329 windowHandle != nullptr ? getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004330 commandEntry->reason = reason;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004331 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004332}
4333
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004334void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004335 mLock.unlock();
4336
4337 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4338
4339 mLock.lock();
4340}
4341
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004342void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004343 sp<Connection> connection = commandEntry->connection;
4344
4345 if (connection->status != Connection::STATUS_ZOMBIE) {
4346 mLock.unlock();
4347
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004348 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004349
4350 mLock.lock();
4351 }
4352}
4353
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004354void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004355 sp<IBinder> oldToken = commandEntry->oldToken;
4356 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004357 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004358 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004359 mLock.lock();
4360}
4361
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004362void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004363 sp<IBinder> token =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004364 commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004365 mLock.unlock();
4366
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004367 nsecs_t newTimeout =
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004368 mPolicy->notifyANR(commandEntry->inputApplicationHandle, token, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004369
4370 mLock.lock();
4371
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004372 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004373}
4374
4375void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4376 CommandEntry* commandEntry) {
4377 KeyEntry* entry = commandEntry->keyEntry;
4378
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004379 KeyEvent event = createKeyEvent(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004380
4381 mLock.unlock();
4382
Michael Wright2b3c3302018-03-02 17:19:13 +00004383 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004384 sp<IBinder> token = commandEntry->inputChannel != nullptr
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004385 ? commandEntry->inputChannel->getConnectionToken()
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004386 : nullptr;
4387 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004388 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4389 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004390 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004391 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004392
4393 mLock.lock();
4394
4395 if (delay < 0) {
4396 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4397 } else if (!delay) {
4398 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4399 } else {
4400 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4401 entry->interceptKeyWakeupTime = now() + delay;
4402 }
4403 entry->release();
4404}
4405
chaviwfd6d3512019-03-25 13:23:49 -07004406void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4407 mLock.unlock();
4408 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4409 mLock.lock();
4410}
4411
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004412void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004413 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004414 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004415 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004416 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004417
4418 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07004419 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004420 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004421 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004422 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004423 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004424
4425 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4426 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4427 std::string msg =
4428 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4429 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4430 dispatchEntry->eventEntry->appendDescription(msg);
4431 ALOGI("%s", msg.c_str());
4432 }
4433
4434 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004435 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004436 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4437 restartEvent =
4438 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004439 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004440 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4441 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4442 handled);
4443 } else {
4444 restartEvent = false;
4445 }
4446
4447 // Dequeue the event and start the next cycle.
4448 // Note that because the lock might have been released, it is possible that the
4449 // contents of the wait queue to have been drained, so we need to double-check
4450 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004451 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4452 if (dispatchEntryIt != connection->waitQueue.end()) {
4453 dispatchEntry = *dispatchEntryIt;
4454 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004455 traceWaitQueueLength(connection);
4456 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004457 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004458 traceOutboundQueueLength(connection);
4459 } else {
4460 releaseDispatchEntry(dispatchEntry);
4461 }
4462 }
4463
4464 // Start the next dispatch cycle for this connection.
4465 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004466}
4467
4468bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004469 DispatchEntry* dispatchEntry,
4470 KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004471 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004472 if (!handled) {
4473 // Report the key as unhandled, since the fallback was not handled.
4474 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4475 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004476 return false;
4477 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004478
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004479 // Get the fallback key state.
4480 // Clear it out after dispatching the UP.
4481 int32_t originalKeyCode = keyEntry->keyCode;
4482 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4483 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4484 connection->inputState.removeFallbackKey(originalKeyCode);
4485 }
4486
4487 if (handled || !dispatchEntry->hasForegroundTarget()) {
4488 // If the application handles the original key for which we previously
4489 // generated a fallback or if the window is not a foreground window,
4490 // then cancel the associated fallback key, if any.
4491 if (fallbackKeyCode != -1) {
4492 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004493#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004494 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004495 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4496 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4497 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004498#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004499 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004500 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004501
4502 mLock.unlock();
4503
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004504 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004505 keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004506
4507 mLock.lock();
4508
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004509 // Cancel the fallback key.
4510 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004511 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004512 "application handled the original non-fallback key "
4513 "or is no longer a foreground target, "
4514 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004515 options.keyCode = fallbackKeyCode;
4516 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004517 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004518 connection->inputState.removeFallbackKey(originalKeyCode);
4519 }
4520 } else {
4521 // If the application did not handle a non-fallback key, first check
4522 // that we are in a good state to perform unhandled key event processing
4523 // Then ask the policy what to do with it.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004524 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN && keyEntry->repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004525 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004526#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004527 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004528 "since this is not an initial down. "
4529 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4530 originalKeyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004531#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004532 return false;
4533 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004534
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004535 // Dispatch the unhandled key to the policy.
4536#if DEBUG_OUTBOUND_EVENT_DETAILS
4537 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004538 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4539 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004540#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004541 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004542
4543 mLock.unlock();
4544
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004545 bool fallback =
4546 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
4547 &event, keyEntry->policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004548
4549 mLock.lock();
4550
4551 if (connection->status != Connection::STATUS_NORMAL) {
4552 connection->inputState.removeFallbackKey(originalKeyCode);
4553 return false;
4554 }
4555
4556 // Latch the fallback keycode for this key on an initial down.
4557 // The fallback keycode cannot change at any other point in the lifecycle.
4558 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004559 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004560 fallbackKeyCode = event.getKeyCode();
4561 } else {
4562 fallbackKeyCode = AKEYCODE_UNKNOWN;
4563 }
4564 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4565 }
4566
4567 ALOG_ASSERT(fallbackKeyCode != -1);
4568
4569 // Cancel the fallback key if the policy decides not to send it anymore.
4570 // We will continue to dispatch the key to the policy but we will no
4571 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004572 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
4573 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004574#if DEBUG_OUTBOUND_EVENT_DETAILS
4575 if (fallback) {
4576 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004577 "as a fallback for %d, but on the DOWN it had requested "
4578 "to send %d instead. Fallback canceled.",
4579 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004580 } else {
4581 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004582 "but on the DOWN it had requested to send %d. "
4583 "Fallback canceled.",
4584 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004585 }
4586#endif
4587
4588 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4589 "canceling fallback, policy no longer desires it");
4590 options.keyCode = fallbackKeyCode;
4591 synthesizeCancelationEventsForConnectionLocked(connection, options);
4592
4593 fallback = false;
4594 fallbackKeyCode = AKEYCODE_UNKNOWN;
4595 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004596 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004597 }
4598 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004599
4600#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004601 {
4602 std::string msg;
4603 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4604 connection->inputState.getFallbackKeys();
4605 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004606 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004607 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004608 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004609 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004610 }
4611#endif
4612
4613 if (fallback) {
4614 // Restart the dispatch cycle using the fallback key.
4615 keyEntry->eventTime = event.getEventTime();
4616 keyEntry->deviceId = event.getDeviceId();
4617 keyEntry->source = event.getSource();
4618 keyEntry->displayId = event.getDisplayId();
4619 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4620 keyEntry->keyCode = fallbackKeyCode;
4621 keyEntry->scanCode = event.getScanCode();
4622 keyEntry->metaState = event.getMetaState();
4623 keyEntry->repeatCount = event.getRepeatCount();
4624 keyEntry->downTime = event.getDownTime();
4625 keyEntry->syntheticRepeat = false;
4626
4627#if DEBUG_OUTBOUND_EVENT_DETAILS
4628 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004629 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4630 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004631#endif
4632 return true; // restart the event
4633 } else {
4634#if DEBUG_OUTBOUND_EVENT_DETAILS
4635 ALOGD("Unhandled key event: No fallback key.");
4636#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004637
4638 // Report the key as unhandled, since there is no fallback key.
4639 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004640 }
4641 }
4642 return false;
4643}
4644
4645bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004646 DispatchEntry* dispatchEntry,
4647 MotionEntry* motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004648 return false;
4649}
4650
4651void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4652 mLock.unlock();
4653
4654 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4655
4656 mLock.lock();
4657}
4658
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004659KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
4660 KeyEvent event;
4661 event.initialize(entry.deviceId, entry.source, entry.displayId, entry.action, entry.flags,
4662 entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount,
4663 entry.downTime, entry.eventTime);
4664 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004665}
4666
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004667void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004668 int32_t injectionResult,
4669 nsecs_t timeSpentWaitingForApplication) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004670 // TODO Write some statistics about how long we spend waiting.
4671}
4672
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05004673/**
4674 * Report the touch event latency to the statsd server.
4675 * Input events are reported for statistics if:
4676 * - This is a touchscreen event
4677 * - InputFilter is not enabled
4678 * - Event is not injected or synthesized
4679 *
4680 * Statistics should be reported before calling addValue, to prevent a fresh new sample
4681 * from getting aggregated with the "old" data.
4682 */
4683void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
4684 REQUIRES(mLock) {
4685 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
4686 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
4687 if (!reportForStatistics) {
4688 return;
4689 }
4690
4691 if (mTouchStatistics.shouldReport()) {
4692 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
4693 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
4694 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
4695 mTouchStatistics.reset();
4696 }
4697 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
4698 mTouchStatistics.addValue(latencyMicros);
4699}
4700
Michael Wrightd02c5b62014-02-10 15:10:22 -08004701void InputDispatcher::traceInboundQueueLengthLocked() {
4702 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004703 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004704 }
4705}
4706
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004707void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004708 if (ATRACE_ENABLED()) {
4709 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004710 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004711 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004712 }
4713}
4714
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004715void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004716 if (ATRACE_ENABLED()) {
4717 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004718 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004719 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004720 }
4721}
4722
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004723void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004724 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004725
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004726 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004727 dumpDispatchStateLocked(dump);
4728
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004729 if (!mLastANRState.empty()) {
4730 dump += "\nInput Dispatcher State at time of last ANR:\n";
4731 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004732 }
4733}
4734
4735void InputDispatcher::monitor() {
4736 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004737 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004738 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004739 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004740}
4741
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08004742/**
4743 * Wake up the dispatcher and wait until it processes all events and commands.
4744 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
4745 * this method can be safely called from any thread, as long as you've ensured that
4746 * the work you are interested in completing has already been queued.
4747 */
4748bool InputDispatcher::waitForIdle() {
4749 /**
4750 * Timeout should represent the longest possible time that a device might spend processing
4751 * events and commands.
4752 */
4753 constexpr std::chrono::duration TIMEOUT = 100ms;
4754 std::unique_lock lock(mLock);
4755 mLooper->wake();
4756 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
4757 return result == std::cv_status::no_timeout;
4758}
4759
Garfield Tane84e6f92019-08-29 17:28:41 -07004760} // namespace android::inputdispatcher