blob: 75bc0aa7c8920c532dfcfe40d481704eec13beb7 [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>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080063#include <input/InputDevice.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070064#include <log/log.h>
Gang Wang342c9272020-01-13 13:15:04 -050065#include <openssl/hmac.h>
66#include <openssl/rand.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070067#include <powermanager/PowerManager.h>
68#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080069
70#define INDENT " "
71#define INDENT2 " "
72#define INDENT3 " "
73#define INDENT4 " "
74
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080075using android::base::StringPrintf;
76
Garfield Tane84e6f92019-08-29 17:28:41 -070077namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080078
79// Default input dispatching timeout if there is no focused application or paused window
80// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000081constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080082
83// Amount of time to allow for all pending events to be processed when an app switch
84// key is on the way. This is used to preempt input dispatch and drop input events
85// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000086constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080087
88// Amount of time to allow for an event to be dispatched (measured since its eventTime)
89// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000090constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080091
92// Amount of time to allow touch events to be streamed out to a connection before requiring
93// that the first event be finished. This value extends the ANR timeout by the specified
94// amount. For example, if streaming is allowed to get ahead by one second relative to the
95// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000096constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080097
98// 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 +000099constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
100
101// Log a warning when an interception call takes longer than this to process.
102constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800103
104// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000105constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
106
Michael Wrightd02c5b62014-02-10 15:10:22 -0800107static inline nsecs_t now() {
108 return systemTime(SYSTEM_TIME_MONOTONIC);
109}
110
111static inline const char* toString(bool value) {
112 return value ? "true" : "false";
113}
114
115static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700116 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
117 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800118}
119
120static bool isValidKeyAction(int32_t action) {
121 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700122 case AKEY_EVENT_ACTION_DOWN:
123 case AKEY_EVENT_ACTION_UP:
124 return true;
125 default:
126 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800127 }
128}
129
130static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700131 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800132 ALOGE("Key event has invalid action code 0x%x", action);
133 return false;
134 }
135 return true;
136}
137
Michael Wright7b159c92015-05-14 14:48:03 +0100138static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800139 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700140 case AMOTION_EVENT_ACTION_DOWN:
141 case AMOTION_EVENT_ACTION_UP:
142 case AMOTION_EVENT_ACTION_CANCEL:
143 case AMOTION_EVENT_ACTION_MOVE:
144 case AMOTION_EVENT_ACTION_OUTSIDE:
145 case AMOTION_EVENT_ACTION_HOVER_ENTER:
146 case AMOTION_EVENT_ACTION_HOVER_MOVE:
147 case AMOTION_EVENT_ACTION_HOVER_EXIT:
148 case AMOTION_EVENT_ACTION_SCROLL:
149 return true;
150 case AMOTION_EVENT_ACTION_POINTER_DOWN:
151 case AMOTION_EVENT_ACTION_POINTER_UP: {
152 int32_t index = getMotionEventActionPointerIndex(action);
153 return index >= 0 && index < pointerCount;
154 }
155 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
156 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
157 return actionButton != 0;
158 default:
159 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800160 }
161}
162
Michael Wright7b159c92015-05-14 14:48:03 +0100163static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700164 const PointerProperties* pointerProperties) {
165 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800166 ALOGE("Motion event has invalid action code 0x%x", action);
167 return false;
168 }
169 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000170 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700171 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800172 return false;
173 }
174 BitSet32 pointerIdBits;
175 for (size_t i = 0; i < pointerCount; i++) {
176 int32_t id = pointerProperties[i].id;
177 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700178 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
179 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800180 return false;
181 }
182 if (pointerIdBits.hasBit(id)) {
183 ALOGE("Motion event has duplicate pointer id %d", id);
184 return false;
185 }
186 pointerIdBits.markBit(id);
187 }
188 return true;
189}
190
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800191static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800192 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800193 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800194 return;
195 }
196
197 bool first = true;
198 Region::const_iterator cur = region.begin();
199 Region::const_iterator const tail = region.end();
200 while (cur != tail) {
201 if (first) {
202 first = false;
203 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800204 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800205 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800206 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800207 cur++;
208 }
209}
210
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700211/**
212 * Find the entry in std::unordered_map by key, and return it.
213 * If the entry is not found, return a default constructed entry.
214 *
215 * Useful when the entries are vectors, since an empty vector will be returned
216 * if the entry is not found.
217 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
218 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700219template <typename K, typename V>
220static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700221 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700222 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800223}
224
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700225/**
226 * Find the entry in std::unordered_map by value, and remove it.
227 * If more than one entry has the same value, then all matching
228 * key-value pairs will be removed.
229 *
230 * Return true if at least one value has been removed.
231 */
232template <typename K, typename V>
233static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
234 bool removed = false;
235 for (auto it = map.begin(); it != map.end();) {
236 if (it->second == value) {
237 it = map.erase(it);
238 removed = true;
239 } else {
240 it++;
241 }
242 }
243 return removed;
244}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800245
chaviwaf87b3e2019-10-01 16:59:28 -0700246static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
247 if (first == second) {
248 return true;
249 }
250
251 if (first == nullptr || second == nullptr) {
252 return false;
253 }
254
255 return first->getToken() == second->getToken();
256}
257
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800258static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
259 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
260}
261
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000262static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
263 EventEntry* eventEntry,
264 int32_t inputTargetFlags) {
265 if (inputTarget.useDefaultPointerInfo()) {
266 const PointerInfo& pointerInfo = inputTarget.getDefaultPointerInfo();
267 return std::make_unique<DispatchEntry>(eventEntry, // increments ref
268 inputTargetFlags, pointerInfo.xOffset,
269 pointerInfo.yOffset, inputTarget.globalScaleFactor,
270 pointerInfo.windowXScale, pointerInfo.windowYScale);
271 }
272
273 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
274 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
275
276 PointerCoords pointerCoords[motionEntry.pointerCount];
277
278 // Use the first pointer information to normalize all other pointers. This could be any pointer
279 // as long as all other pointers are normalized to the same value and the final DispatchEntry
280 // uses the offset and scale for the normalized pointer.
281 const PointerInfo& firstPointerInfo =
282 inputTarget.pointerInfos[inputTarget.pointerIds.firstMarkedBit()];
283
284 // Iterate through all pointers in the event to normalize against the first.
285 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
286 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
287 uint32_t pointerId = uint32_t(pointerProperties.id);
288 const PointerInfo& currPointerInfo = inputTarget.pointerInfos[pointerId];
289
290 // The scale factor is the ratio of the current pointers scale to the normalized scale.
291 float scaleXDiff = currPointerInfo.windowXScale / firstPointerInfo.windowXScale;
292 float scaleYDiff = currPointerInfo.windowYScale / firstPointerInfo.windowYScale;
293
294 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
295 // First apply the current pointers offset to set the window at 0,0
296 pointerCoords[pointerIndex].applyOffset(currPointerInfo.xOffset, currPointerInfo.yOffset);
297 // Next scale the coordinates.
298 pointerCoords[pointerIndex].scale(1, scaleXDiff, scaleYDiff);
299 // Lastly, offset the coordinates so they're in the normalized pointer's frame.
300 pointerCoords[pointerIndex].applyOffset(-firstPointerInfo.xOffset,
301 -firstPointerInfo.yOffset);
302 }
303
304 MotionEntry* combinedMotionEntry =
305 new MotionEntry(motionEntry.sequenceNum, motionEntry.eventTime, motionEntry.deviceId,
306 motionEntry.source, motionEntry.displayId, motionEntry.policyFlags,
307 motionEntry.action, motionEntry.actionButton, motionEntry.flags,
308 motionEntry.metaState, motionEntry.buttonState,
309 motionEntry.classification, motionEntry.edgeFlags,
310 motionEntry.xPrecision, motionEntry.yPrecision,
311 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
312 motionEntry.downTime, motionEntry.pointerCount,
313 motionEntry.pointerProperties, pointerCoords, 0 /* xOffset */,
314 0 /* yOffset */);
315
316 if (motionEntry.injectionState) {
317 combinedMotionEntry->injectionState = motionEntry.injectionState;
318 combinedMotionEntry->injectionState->refCount += 1;
319 }
320
321 std::unique_ptr<DispatchEntry> dispatchEntry =
322 std::make_unique<DispatchEntry>(combinedMotionEntry, // increments ref
323 inputTargetFlags, firstPointerInfo.xOffset,
324 firstPointerInfo.yOffset, inputTarget.globalScaleFactor,
325 firstPointerInfo.windowXScale,
326 firstPointerInfo.windowYScale);
327 combinedMotionEntry->release();
328 return dispatchEntry;
329}
330
Gang Wang342c9272020-01-13 13:15:04 -0500331static std::array<uint8_t, 128> getRandomKey() {
332 std::array<uint8_t, 128> key;
333 if (RAND_bytes(key.data(), key.size()) != 1) {
334 LOG_ALWAYS_FATAL("Can't generate HMAC key");
335 }
336 return key;
337}
338
339// --- HmacKeyManager ---
340
341HmacKeyManager::HmacKeyManager() : mHmacKey(getRandomKey()) {}
342
343std::array<uint8_t, 32> HmacKeyManager::sign(const VerifiedInputEvent& event) const {
344 size_t size;
345 switch (event.type) {
346 case VerifiedInputEvent::Type::KEY: {
347 size = sizeof(VerifiedKeyEvent);
348 break;
349 }
350 case VerifiedInputEvent::Type::MOTION: {
351 size = sizeof(VerifiedMotionEvent);
352 break;
353 }
354 }
355 std::vector<uint8_t> data;
356 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
357 data.assign(start, start + size);
358 return sign(data);
359}
360
361std::array<uint8_t, 32> HmacKeyManager::sign(const std::vector<uint8_t>& data) const {
362 // SHA256 always generates 32-bytes result
363 std::array<uint8_t, 32> hash;
364 unsigned int hashLen = 0;
365 uint8_t* result = HMAC(EVP_sha256(), mHmacKey.data(), mHmacKey.size(), data.data(), data.size(),
366 hash.data(), &hashLen);
367 if (result == nullptr) {
368 ALOGE("Could not sign the data using HMAC");
369 return INVALID_HMAC;
370 }
371
372 if (hashLen != hash.size()) {
373 ALOGE("HMAC-SHA256 has unexpected length");
374 return INVALID_HMAC;
375 }
376
377 return hash;
378}
379
Michael Wrightd02c5b62014-02-10 15:10:22 -0800380// --- InputDispatcher ---
381
Garfield Tan00f511d2019-06-12 16:55:40 -0700382InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
383 : mPolicy(policy),
384 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700385 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tan00f511d2019-06-12 16:55:40 -0700386 mAppSwitchSawKeyDown(false),
387 mAppSwitchDueTime(LONG_LONG_MAX),
388 mNextUnblockedEvent(nullptr),
389 mDispatchEnabled(false),
390 mDispatchFrozen(false),
391 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800392 // mInTouchMode will be initialized by the WindowManager to the default device config.
393 // To avoid leaking stack in case that call never comes, and for tests,
394 // initialize it here anyways.
395 mInTouchMode(true),
Garfield Tan00f511d2019-06-12 16:55:40 -0700396 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
397 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800398 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800399 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800400
Yi Kong9b14ac62018-07-17 13:48:38 -0700401 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800402
403 policy->getDispatcherConfiguration(&mConfig);
404}
405
406InputDispatcher::~InputDispatcher() {
407 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800408 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800409
410 resetKeyRepeatLocked();
411 releasePendingEventLocked();
412 drainInboundQueueLocked();
413 }
414
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700415 while (!mConnectionsByFd.empty()) {
416 sp<Connection> connection = mConnectionsByFd.begin()->second;
417 unregisterInputChannel(connection->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800418 }
419}
420
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700421status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700422 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700423 return ALREADY_EXISTS;
424 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700425 mThread = std::make_unique<InputThread>(
426 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
427 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700428}
429
430status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700431 if (mThread && mThread->isCallingThread()) {
432 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700433 return INVALID_OPERATION;
434 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700435 mThread.reset();
436 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700437}
438
Michael Wrightd02c5b62014-02-10 15:10:22 -0800439void InputDispatcher::dispatchOnce() {
440 nsecs_t nextWakeupTime = LONG_LONG_MAX;
441 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800442 std::scoped_lock _l(mLock);
443 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800444
445 // Run a dispatch loop if there are no pending commands.
446 // The dispatch loop might enqueue commands to run afterwards.
447 if (!haveCommandsLocked()) {
448 dispatchOnceInnerLocked(&nextWakeupTime);
449 }
450
451 // Run all pending commands if there are any.
452 // If any commands were run then force the next poll to wake up immediately.
453 if (runCommandsLockedInterruptible()) {
454 nextWakeupTime = LONG_LONG_MIN;
455 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800456
457 // We are about to enter an infinitely long sleep, because we have no commands or
458 // pending or queued events
459 if (nextWakeupTime == LONG_LONG_MAX) {
460 mDispatcherEnteredIdle.notify_all();
461 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800462 } // release lock
463
464 // Wait for callback or timeout or wake. (make sure we round up, not down)
465 nsecs_t currentTime = now();
466 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
467 mLooper->pollOnce(timeoutMillis);
468}
469
470void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
471 nsecs_t currentTime = now();
472
Jeff Browndc5992e2014-04-11 01:27:26 -0700473 // Reset the key repeat timer whenever normal dispatch is suspended while the
474 // device is in a non-interactive state. This is to ensure that we abort a key
475 // repeat if the device is just coming out of sleep.
476 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800477 resetKeyRepeatLocked();
478 }
479
480 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
481 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100482 if (DEBUG_FOCUS) {
483 ALOGD("Dispatch frozen. Waiting some more.");
484 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800485 return;
486 }
487
488 // Optimize latency of app switches.
489 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
490 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
491 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
492 if (mAppSwitchDueTime < *nextWakeupTime) {
493 *nextWakeupTime = mAppSwitchDueTime;
494 }
495
496 // Ready to start a new event.
497 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700498 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700499 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800500 if (isAppSwitchDue) {
501 // The inbound queue is empty so the app switch key we were waiting
502 // for will never arrive. Stop waiting for it.
503 resetPendingAppSwitchLocked(false);
504 isAppSwitchDue = false;
505 }
506
507 // Synthesize a key repeat if appropriate.
508 if (mKeyRepeatState.lastKeyEntry) {
509 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
510 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
511 } else {
512 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
513 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
514 }
515 }
516 }
517
518 // Nothing to do if there is no pending event.
519 if (!mPendingEvent) {
520 return;
521 }
522 } else {
523 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700524 mPendingEvent = mInboundQueue.front();
525 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800526 traceInboundQueueLengthLocked();
527 }
528
529 // Poke user activity for this event.
530 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700531 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800532 }
533
534 // Get ready to dispatch the event.
535 resetANRTimeoutsLocked();
536 }
537
538 // Now we have an event to dispatch.
539 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700540 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800541 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700542 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800543 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700544 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800545 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700546 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800547 }
548
549 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700550 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800551 }
552
553 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700554 case EventEntry::Type::CONFIGURATION_CHANGED: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700555 ConfigurationChangedEntry* typedEntry =
556 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
557 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700558 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700559 break;
560 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800561
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700562 case EventEntry::Type::DEVICE_RESET: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700563 DeviceResetEntry* typedEntry = static_cast<DeviceResetEntry*>(mPendingEvent);
564 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700565 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700566 break;
567 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800568
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100569 case EventEntry::Type::FOCUS: {
570 FocusEntry* typedEntry = static_cast<FocusEntry*>(mPendingEvent);
571 dispatchFocusLocked(currentTime, typedEntry);
572 done = true;
573 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
574 break;
575 }
576
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700577 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700578 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
579 if (isAppSwitchDue) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700580 if (isAppSwitchKeyEvent(*typedEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700581 resetPendingAppSwitchLocked(true);
582 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700583 } else if (dropReason == DropReason::NOT_DROPPED) {
584 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700585 }
586 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700587 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700588 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700589 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700590 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
591 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700592 }
593 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
594 break;
595 }
596
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700597 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700598 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700599 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
600 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800601 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700602 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700603 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700604 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700605 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
606 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700607 }
608 done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
609 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800610 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800611 }
612
613 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700614 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700615 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800616 }
Michael Wright3a981722015-06-10 15:26:13 +0100617 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800618
619 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700620 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800621 }
622}
623
624bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700625 bool needWake = mInboundQueue.empty();
626 mInboundQueue.push_back(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800627 traceInboundQueueLengthLocked();
628
629 switch (entry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700630 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700631 // Optimize app switch latency.
632 // If the application takes too long to catch up then we drop all events preceding
633 // the app switch key.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700634 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700635 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700636 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700637 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700638 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700639 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800640#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700641 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800642#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700643 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700644 mAppSwitchSawKeyDown = false;
645 needWake = true;
646 }
647 }
648 }
649 break;
650 }
651
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700652 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700653 // Optimize case where the current application is unresponsive and the user
654 // decides to touch a window in a different application.
655 // If the application takes too long to catch up then we drop all events preceding
656 // the touch into the other window.
657 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
658 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN &&
659 (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
660 mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY &&
661 mInputTargetWaitApplicationToken != nullptr) {
662 int32_t displayId = motionEntry->displayId;
663 int32_t x =
664 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
665 int32_t y =
666 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
667 sp<InputWindowHandle> touchedWindowHandle =
668 findTouchedWindowAtLocked(displayId, x, y);
669 if (touchedWindowHandle != nullptr &&
670 touchedWindowHandle->getApplicationToken() !=
671 mInputTargetWaitApplicationToken) {
672 // User touched a different application than the one we are waiting on.
673 // Flag the event, and start pruning the input queue.
674 mNextUnblockedEvent = motionEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800675 needWake = true;
676 }
677 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700678 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800679 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700680 case EventEntry::Type::CONFIGURATION_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100681 case EventEntry::Type::DEVICE_RESET:
682 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700683 // nothing to do
684 break;
685 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800686 }
687
688 return needWake;
689}
690
691void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
692 entry->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700693 mRecentQueue.push_back(entry);
694 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
695 mRecentQueue.front()->release();
696 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800697 }
698}
699
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700700sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
701 int32_t y, bool addOutsideTargets,
702 bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800703 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800704 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
705 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800706 const InputWindowInfo* windowInfo = windowHandle->getInfo();
707 if (windowInfo->displayId == displayId) {
708 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800709
710 if (windowInfo->visible) {
711 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700712 bool isTouchModal = (flags &
713 (InputWindowInfo::FLAG_NOT_FOCUSABLE |
714 InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800715 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800716 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700717 if (portalToDisplayId != ADISPLAY_ID_NONE &&
718 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800719 if (addPortalWindows) {
720 // For the monitoring channels of the display.
721 mTempTouchState.addPortalWindow(windowHandle);
722 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700723 return findTouchedWindowAtLocked(portalToDisplayId, x, y,
724 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800725 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800726 // Found window.
727 return windowHandle;
728 }
729 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800730
731 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700732 mTempTouchState.addOrUpdateWindow(windowHandle,
733 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
734 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800735 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800736 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800737 }
738 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700739 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800740}
741
Garfield Tane84e6f92019-08-29 17:28:41 -0700742std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +0000743 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
744 std::vector<TouchedMonitor> touchedMonitors;
745
746 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
747 addGestureMonitors(monitors, touchedMonitors);
748 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
749 const InputWindowInfo* windowInfo = portalWindow->getInfo();
750 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700751 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
752 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000753 }
754 return touchedMonitors;
755}
756
757void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700758 std::vector<TouchedMonitor>& outTouchedMonitors,
759 float xOffset, float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000760 if (monitors.empty()) {
761 return;
762 }
763 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
764 for (const Monitor& monitor : monitors) {
765 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
766 }
767}
768
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700769void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800770 const char* reason;
771 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700772 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800773#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700774 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800775#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700776 reason = "inbound event was dropped because the policy consumed it";
777 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700778 case DropReason::DISABLED:
779 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700780 ALOGI("Dropped event because input dispatch is disabled.");
781 }
782 reason = "inbound event was dropped because input dispatch is disabled";
783 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700784 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700785 ALOGI("Dropped event because of pending overdue app switch.");
786 reason = "inbound event was dropped because of pending overdue app switch";
787 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700788 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700789 ALOGI("Dropped event because the current application is not responding and the user "
790 "has started interacting with a different application.");
791 reason = "inbound event was dropped because the current application is not responding "
792 "and the user has started interacting with a different application";
793 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700794 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700795 ALOGI("Dropped event because it is stale.");
796 reason = "inbound event was dropped because it is stale";
797 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700798 case DropReason::NOT_DROPPED: {
799 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700800 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700801 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800802 }
803
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700804 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700805 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800806 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
807 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700808 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800809 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700810 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700811 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
812 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700813 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
814 synthesizeCancelationEventsForAllConnectionsLocked(options);
815 } else {
816 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
817 synthesizeCancelationEventsForAllConnectionsLocked(options);
818 }
819 break;
820 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100821 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700822 case EventEntry::Type::CONFIGURATION_CHANGED:
823 case EventEntry::Type::DEVICE_RESET: {
824 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
825 break;
826 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800827 }
828}
829
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800830static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700831 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
832 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800833}
834
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700835bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
836 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
837 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
838 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800839}
840
841bool InputDispatcher::isAppSwitchPendingLocked() {
842 return mAppSwitchDueTime != LONG_LONG_MAX;
843}
844
845void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
846 mAppSwitchDueTime = LONG_LONG_MAX;
847
848#if DEBUG_APP_SWITCH
849 if (handled) {
850 ALOGD("App switch has arrived.");
851 } else {
852 ALOGD("App switch was abandoned.");
853 }
854#endif
855}
856
Michael Wrightd02c5b62014-02-10 15:10:22 -0800857bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700858 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800859}
860
861bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700862 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800863 return false;
864 }
865
866 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700867 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700868 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800869 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700870 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800871
872 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700873 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800874 return true;
875}
876
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700877void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
878 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800879}
880
881void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700882 while (!mInboundQueue.empty()) {
883 EventEntry* entry = mInboundQueue.front();
884 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800885 releaseInboundEventLocked(entry);
886 }
887 traceInboundQueueLengthLocked();
888}
889
890void InputDispatcher::releasePendingEventLocked() {
891 if (mPendingEvent) {
892 resetANRTimeoutsLocked();
893 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700894 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800895 }
896}
897
898void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
899 InjectionState* injectionState = entry->injectionState;
900 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
901#if DEBUG_DISPATCH_CYCLE
902 ALOGD("Injected inbound event was dropped.");
903#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800904 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800905 }
906 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700907 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800908 }
909 addRecentEventLocked(entry);
910 entry->release();
911}
912
913void InputDispatcher::resetKeyRepeatLocked() {
914 if (mKeyRepeatState.lastKeyEntry) {
915 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700916 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800917 }
918}
919
Garfield Tane84e6f92019-08-29 17:28:41 -0700920KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800921 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
922
923 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700924 uint32_t policyFlags = entry->policyFlags &
925 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800926 if (entry->refCount == 1) {
927 entry->recycle();
928 entry->eventTime = currentTime;
929 entry->policyFlags = policyFlags;
930 entry->repeatCount += 1;
931 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700932 KeyEntry* newEntry =
933 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, entry->deviceId,
934 entry->source, entry->displayId, policyFlags, entry->action,
935 entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
936 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800937
938 mKeyRepeatState.lastKeyEntry = newEntry;
939 entry->release();
940
941 entry = newEntry;
942 }
943 entry->syntheticRepeat = true;
944
945 // Increment reference count since we keep a reference to the event in
946 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
947 entry->refCount += 1;
948
949 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
950 return entry;
951}
952
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700953bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
954 ConfigurationChangedEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800955#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700956 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800957#endif
958
959 // Reset key repeating in case a keyboard device was added or removed or something.
960 resetKeyRepeatLocked();
961
962 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700963 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
964 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800965 commandEntry->eventTime = entry->eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700966 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800967 return true;
968}
969
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700970bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceResetEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800971#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700972 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700973 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800974#endif
975
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700976 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800977 options.deviceId = entry->deviceId;
978 synthesizeCancelationEventsForAllConnectionsLocked(options);
979 return true;
980}
981
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100982void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) {
983 FocusEntry* focusEntry =
984 new FocusEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, now(), window.getToken(), hasFocus);
985 enqueueInboundEventLocked(focusEntry);
986}
987
988void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) {
989 sp<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
990 if (channel == nullptr) {
991 return; // Window has gone away
992 }
993 InputTarget target;
994 target.inputChannel = channel;
995 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
996 entry->dispatchInProgress = true;
997
998 dispatchEventLocked(currentTime, entry, {target});
999}
1000
Michael Wrightd02c5b62014-02-10 15:10:22 -08001001bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001002 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001003 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001004 if (!entry->dispatchInProgress) {
1005 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1006 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1007 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1008 if (mKeyRepeatState.lastKeyEntry &&
1009 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001010 // We have seen two identical key downs in a row which indicates that the device
1011 // driver is automatically generating key repeats itself. We take note of the
1012 // repeat here, but we disable our own next key repeat timer since it is clear that
1013 // we will not need to synthesize key repeats ourselves.
1014 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1015 resetKeyRepeatLocked();
1016 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1017 } else {
1018 // Not a repeat. Save key down state in case we do see a repeat later.
1019 resetKeyRepeatLocked();
1020 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1021 }
1022 mKeyRepeatState.lastKeyEntry = entry;
1023 entry->refCount += 1;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001024 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001025 resetKeyRepeatLocked();
1026 }
1027
1028 if (entry->repeatCount == 1) {
1029 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1030 } else {
1031 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1032 }
1033
1034 entry->dispatchInProgress = true;
1035
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001036 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001037 }
1038
1039 // Handle case where the policy asked us to try again later last time.
1040 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1041 if (currentTime < entry->interceptKeyWakeupTime) {
1042 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1043 *nextWakeupTime = entry->interceptKeyWakeupTime;
1044 }
1045 return false; // wait until next wakeup
1046 }
1047 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1048 entry->interceptKeyWakeupTime = 0;
1049 }
1050
1051 // Give the policy a chance to intercept the key.
1052 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1053 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001054 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001055 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +08001056 sp<InputWindowHandle> focusedWindowHandle =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001057 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(*entry));
Tiger Huang721e26f2018-07-24 22:26:19 +08001058 if (focusedWindowHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001059 commandEntry->inputChannel = getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001060 }
1061 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001062 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001063 entry->refCount += 1;
1064 return false; // wait for the command to run
1065 } else {
1066 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1067 }
1068 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001069 if (*dropReason == DropReason::NOT_DROPPED) {
1070 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001071 }
1072 }
1073
1074 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001075 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001076 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001077 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001078 : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08001079 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080 return true;
1081 }
1082
1083 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001084 std::vector<InputTarget> inputTargets;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001085 int32_t injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001086 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001087 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1088 return false;
1089 }
1090
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001091 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001092 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
1093 return true;
1094 }
1095
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001096 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001097 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001098
1099 // Dispatch the key.
1100 dispatchEventLocked(currentTime, entry, inputTargets);
1101 return true;
1102}
1103
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001104void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001105#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001106 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001107 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1108 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001109 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1110 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1111 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001112#endif
1113}
1114
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001115bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry,
1116 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001117 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001118 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001119 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001120 entry->dispatchInProgress = true;
1121
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001122 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001123 }
1124
1125 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001126 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001127 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001128 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001129 : INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130 return true;
1131 }
1132
1133 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1134
1135 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001136 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001137
1138 bool conflictingPointerActions = false;
1139 int32_t injectionResult;
1140 if (isPointerEvent) {
1141 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001142 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001143 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001144 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001145 } else {
1146 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001147 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001148 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001149 }
1150 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1151 return false;
1152 }
1153
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001154 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001155 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001156 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001157 CancelationOptions::Mode mode(isPointerEvent
1158 ? CancelationOptions::CANCEL_POINTER_EVENTS
1159 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001160 CancelationOptions options(mode, "input event injection failed");
1161 synthesizeCancelationEventsForMonitorsLocked(options);
1162 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001163 return true;
1164 }
1165
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001166 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001167 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001168
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001169 if (isPointerEvent) {
1170 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1171 if (stateIndex >= 0) {
1172 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001173 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001174 // The event has gone through these portal windows, so we add monitoring targets of
1175 // the corresponding displays as well.
1176 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001177 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001178 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001179 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001180 }
1181 }
1182 }
1183 }
1184
Michael Wrightd02c5b62014-02-10 15:10:22 -08001185 // Dispatch the motion.
1186 if (conflictingPointerActions) {
1187 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001188 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001189 synthesizeCancelationEventsForAllConnectionsLocked(options);
1190 }
1191 dispatchEventLocked(currentTime, entry, inputTargets);
1192 return true;
1193}
1194
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001195void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001196#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001197 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001198 ", policyFlags=0x%x, "
1199 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1200 "metaState=0x%x, buttonState=0x%x,"
1201 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001202 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1203 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1204 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001205
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001206 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001207 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001208 "x=%f, y=%f, pressure=%f, size=%f, "
1209 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1210 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001211 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1212 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1213 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1214 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1215 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1216 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1217 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1218 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1219 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1220 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001221 }
1222#endif
1223}
1224
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001225void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* eventEntry,
1226 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001227 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001228#if DEBUG_DISPATCH_CYCLE
1229 ALOGD("dispatchEventToCurrentInputTargets");
1230#endif
1231
1232 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1233
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001234 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001235
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001236 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001237 sp<Connection> connection =
1238 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001239 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001240 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001241 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001242 if (DEBUG_FOCUS) {
1243 ALOGD("Dropping event delivery to target with channel '%s' because it "
1244 "is no longer registered with the input dispatcher.",
1245 inputTarget.inputChannel->getName().c_str());
1246 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001247 }
1248 }
1249}
1250
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001251int32_t InputDispatcher::handleTargetsNotReadyLocked(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001252 nsecs_t currentTime, const EventEntry& entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001253 const sp<InputApplicationHandle>& applicationHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001254 const sp<InputWindowHandle>& windowHandle, nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001255 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001256 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001257 if (DEBUG_FOCUS) {
1258 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1259 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001260 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1261 mInputTargetWaitStartTime = currentTime;
1262 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1263 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001264 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001265 }
1266 } else {
1267 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001268 if (DEBUG_FOCUS) {
1269 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
1270 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), reason);
1271 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001272 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001273 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001274 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001275 } else if (applicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001276 timeout =
1277 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001278 } else {
1279 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1280 }
1281
1282 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1283 mInputTargetWaitStartTime = currentTime;
1284 mInputTargetWaitTimeoutTime = currentTime + timeout;
1285 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001286 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001287
Yi Kong9b14ac62018-07-17 13:48:38 -07001288 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001289 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001290 }
Robert Carr740167f2018-10-11 19:03:41 -07001291 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1292 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001293 }
1294 }
1295 }
1296
1297 if (mInputTargetWaitTimeoutExpired) {
1298 return INPUT_EVENT_INJECTION_TIMED_OUT;
1299 }
1300
1301 if (currentTime >= mInputTargetWaitTimeoutTime) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001302 onANRLocked(currentTime, applicationHandle, windowHandle, entry.eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001303 mInputTargetWaitStartTime, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001304
1305 // Force poll loop to wake up immediately on next iteration once we get the
1306 // ANR response back from the policy.
1307 *nextWakeupTime = LONG_LONG_MIN;
1308 return INPUT_EVENT_INJECTION_PENDING;
1309 } else {
1310 // Force poll loop to wake up when timeout is due.
1311 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1312 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1313 }
1314 return INPUT_EVENT_INJECTION_PENDING;
1315 }
1316}
1317
Robert Carr803535b2018-08-02 16:38:15 -07001318void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1319 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1320 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1321 state.removeWindowByToken(token);
1322 }
1323}
1324
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001325void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001326 nsecs_t newTimeout, const sp<IBinder>& inputConnectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001327 if (newTimeout > 0) {
1328 // Extend the timeout.
1329 mInputTargetWaitTimeoutTime = now() + newTimeout;
1330 } else {
1331 // Give up.
1332 mInputTargetWaitTimeoutExpired = true;
1333
1334 // Input state will not be realistic. Mark it out of sync.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001335 sp<Connection> connection = getConnectionLocked(inputConnectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001336 if (connection != nullptr) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001337 removeWindowByTokenLocked(inputConnectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001338
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001339 if (connection->status == Connection::STATUS_NORMAL) {
1340 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1341 "application not responding");
1342 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001343 }
1344 }
1345 }
1346}
1347
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001348nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001349 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1350 return currentTime - mInputTargetWaitStartTime;
1351 }
1352 return 0;
1353}
1354
1355void InputDispatcher::resetANRTimeoutsLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001356 if (DEBUG_FOCUS) {
1357 ALOGD("Resetting ANR timeouts.");
1358 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001359
1360 // Reset input target wait timeout.
1361 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001362 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001363}
1364
Tiger Huang721e26f2018-07-24 22:26:19 +08001365/**
1366 * Get the display id that the given event should go to. If this event specifies a valid display id,
1367 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1368 * Focused display is the display that the user most recently interacted with.
1369 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001370int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001371 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001372 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001373 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001374 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1375 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001376 break;
1377 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001378 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001379 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1380 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001381 break;
1382 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001383 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001384 case EventEntry::Type::CONFIGURATION_CHANGED:
1385 case EventEntry::Type::DEVICE_RESET: {
1386 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001387 return ADISPLAY_ID_NONE;
1388 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001389 }
1390 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1391}
1392
Michael Wrightd02c5b62014-02-10 15:10:22 -08001393int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001394 const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001395 std::vector<InputTarget>& inputTargets,
1396 nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001397 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001398 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001399
Tiger Huang721e26f2018-07-24 22:26:19 +08001400 int32_t displayId = getTargetDisplayId(entry);
1401 sp<InputWindowHandle> focusedWindowHandle =
1402 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1403 sp<InputApplicationHandle> focusedApplicationHandle =
1404 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1405
Michael Wrightd02c5b62014-02-10 15:10:22 -08001406 // If there is no currently focused window and no focused application
1407 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001408 if (focusedWindowHandle == nullptr) {
1409 if (focusedApplicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001410 injectionResult =
1411 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1412 nullptr, nextWakeupTime,
1413 "Waiting because no window has focus but there is "
1414 "a focused application that may eventually add a "
1415 "window when it finishes starting up.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001416 goto Unresponsive;
1417 }
1418
Arthur Hung3b413f22018-10-26 18:05:34 +08001419 ALOGI("Dropping event because there is no focused window or focused application in display "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001420 "%" PRId32 ".",
1421 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001422 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1423 goto Failed;
1424 }
1425
1426 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001427 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001428 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1429 goto Failed;
1430 }
1431
Jeff Brownffb49772014-10-10 19:01:34 -07001432 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001433 reason = checkWindowReadyForMoreInputLocked(currentTime, focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001434 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001435 injectionResult =
1436 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1437 focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001438 goto Unresponsive;
1439 }
1440
1441 // Success! Output targets.
1442 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001443 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001444 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1445 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001446
1447 // Done.
1448Failed:
1449Unresponsive:
1450 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001451 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001452 if (DEBUG_FOCUS) {
1453 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1454 "timeSpentWaitingForApplication=%0.1fms",
1455 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1456 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001457 return injectionResult;
1458}
1459
1460int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001461 const MotionEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001462 std::vector<InputTarget>& inputTargets,
1463 nsecs_t* nextWakeupTime,
1464 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001465 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001466 enum InjectionPermission {
1467 INJECTION_PERMISSION_UNKNOWN,
1468 INJECTION_PERMISSION_GRANTED,
1469 INJECTION_PERMISSION_DENIED
1470 };
1471
Michael Wrightd02c5b62014-02-10 15:10:22 -08001472 // For security reasons, we defer updating the touch state until we are sure that
1473 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001474 int32_t displayId = entry.displayId;
1475 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001476 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1477
1478 // Update the touch state as needed based on the properties of the touch event.
1479 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1480 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1481 sp<InputWindowHandle> newHoverWindowHandle;
1482
Jeff Brownf086ddb2014-02-11 14:28:48 -08001483 // Copy current touch state into mTempTouchState.
1484 // This state is always reset at the end of this function, so if we don't find state
1485 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001486 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001487 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1488 if (oldStateIndex >= 0) {
1489 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1490 mTempTouchState.copyFrom(*oldState);
1491 }
1492
1493 bool isSplit = mTempTouchState.split;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001494 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0 &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001495 (mTempTouchState.deviceId != entry.deviceId || mTempTouchState.source != entry.source ||
1496 mTempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001497 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1498 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1499 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1500 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1501 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001502 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001503 bool wrongDevice = false;
1504 if (newGesture) {
1505 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001506 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001507 if (DEBUG_FOCUS) {
1508 ALOGD("Dropping event because a pointer for a different device is already down "
1509 "in display %" PRId32,
1510 displayId);
1511 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001512 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001513 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1514 switchedDevice = false;
1515 wrongDevice = true;
1516 goto Failed;
1517 }
1518 mTempTouchState.reset();
1519 mTempTouchState.down = down;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001520 mTempTouchState.deviceId = entry.deviceId;
1521 mTempTouchState.source = entry.source;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001522 mTempTouchState.displayId = displayId;
1523 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001524 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001525 if (DEBUG_FOCUS) {
1526 ALOGI("Dropping move event because a pointer for a different device is already active "
1527 "in display %" PRId32,
1528 displayId);
1529 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001530 // TODO: test multiple simultaneous input streams.
1531 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1532 switchedDevice = false;
1533 wrongDevice = true;
1534 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001535 }
1536
1537 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1538 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1539
Garfield Tan00f511d2019-06-12 16:55:40 -07001540 int32_t x;
1541 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001542 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001543 // Always dispatch mouse events to cursor position.
1544 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001545 x = int32_t(entry.xCursorPosition);
1546 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001547 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001548 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1549 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001550 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001551 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001552 sp<InputWindowHandle> newTouchedWindowHandle =
1553 findTouchedWindowAtLocked(displayId, x, y, isDown /*addOutsideTargets*/,
1554 true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001555
1556 std::vector<TouchedMonitor> newGestureMonitors = isDown
1557 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1558 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001559
Michael Wrightd02c5b62014-02-10 15:10:22 -08001560 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001561 if (newTouchedWindowHandle != nullptr &&
1562 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001563 // New window supports splitting, but we should never split mouse events.
1564 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001565 } else if (isSplit) {
1566 // New window does not support splitting but we have already split events.
1567 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001568 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001569 }
1570
1571 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001572 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001573 // Try to assign the pointer to the first foreground window we find, if there is one.
1574 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001575 }
1576
1577 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1578 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001579 "(%d, %d) in display %" PRId32 ".",
1580 x, y, displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00001581 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1582 goto Failed;
1583 }
1584
1585 if (newTouchedWindowHandle != nullptr) {
1586 // Set target flags.
1587 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1588 if (isSplit) {
1589 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001590 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001591 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1592 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1593 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1594 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1595 }
1596
1597 // Update hover state.
1598 if (isHoverAction) {
1599 newHoverWindowHandle = newTouchedWindowHandle;
1600 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1601 newHoverWindowHandle = mLastHoverWindowHandle;
1602 }
1603
1604 // Update the temporary touch state.
1605 BitSet32 pointerIds;
1606 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001607 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001608 pointerIds.markBit(pointerId);
1609 }
1610 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001611 }
1612
Michael Wright3dd60e22019-03-27 22:06:44 +00001613 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001614 } else {
1615 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1616
1617 // If the pointer is not currently down, then ignore the event.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001618 if (!mTempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001619 if (DEBUG_FOCUS) {
1620 ALOGD("Dropping event because the pointer is not down or we previously "
1621 "dropped the pointer down event in display %" PRId32,
1622 displayId);
1623 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001624 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1625 goto Failed;
1626 }
1627
1628 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001629 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001630 mTempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001631 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1632 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001633
1634 sp<InputWindowHandle> oldTouchedWindowHandle =
1635 mTempTouchState.getFirstForegroundWindowHandle();
1636 sp<InputWindowHandle> newTouchedWindowHandle =
1637 findTouchedWindowAtLocked(displayId, x, y);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001638 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1639 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001640 if (DEBUG_FOCUS) {
1641 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1642 oldTouchedWindowHandle->getName().c_str(),
1643 newTouchedWindowHandle->getName().c_str(), displayId);
1644 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001645 // Make a slippery exit from the old window.
1646 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001647 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1648 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001649
1650 // Make a slippery entrance into the new window.
1651 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1652 isSplit = true;
1653 }
1654
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001655 int32_t targetFlags =
1656 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001657 if (isSplit) {
1658 targetFlags |= InputTarget::FLAG_SPLIT;
1659 }
1660 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1661 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1662 }
1663
1664 BitSet32 pointerIds;
1665 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001666 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001667 }
1668 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1669 }
1670 }
1671 }
1672
1673 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1674 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001675 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001676#if DEBUG_HOVER
1677 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001678 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001679#endif
1680 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001681 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT,
1682 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001683 }
1684
1685 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001686 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001687#if DEBUG_HOVER
1688 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001689 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001690#endif
1691 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001692 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1693 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001694 }
1695 }
1696
1697 // Check permission to inject into all touched foreground windows and ensure there
1698 // is at least one touched foreground window.
1699 {
1700 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001701 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001702 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1703 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001704 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001705 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1706 injectionPermission = INJECTION_PERMISSION_DENIED;
1707 goto Failed;
1708 }
1709 }
1710 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001711 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1712 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001713 if (DEBUG_FOCUS) {
1714 ALOGD("Dropping event because there is no touched foreground window in display "
1715 "%" PRId32 " or gesture monitor to receive it.",
1716 displayId);
1717 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001718 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1719 goto Failed;
1720 }
1721
1722 // Permission granted to injection into all touched foreground windows.
1723 injectionPermission = INJECTION_PERMISSION_GRANTED;
1724 }
1725
1726 // Check whether windows listening for outside touches are owned by the same UID. If it is
1727 // set the policy flag that we will not reveal coordinate information to this window.
1728 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1729 sp<InputWindowHandle> foregroundWindowHandle =
1730 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001731 if (foregroundWindowHandle) {
1732 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1733 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1734 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1735 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1736 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1737 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001738 InputTarget::FLAG_ZERO_COORDS,
1739 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001740 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001741 }
1742 }
1743 }
1744 }
1745
1746 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001747 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001748 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001749 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001750 std::string reason =
1751 checkWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle,
1752 entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001753 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001754 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, nullptr,
1755 touchedWindow.windowHandle,
1756 nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001757 goto Unresponsive;
1758 }
1759 }
1760 }
1761
1762 // If this is the first pointer going down and the touched window has a wallpaper
1763 // then also add the touched wallpaper windows so they are locked in for the duration
1764 // of the touch gesture.
1765 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1766 // engine only supports touch events. We would need to add a mechanism similar
1767 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1768 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1769 sp<InputWindowHandle> foregroundWindowHandle =
1770 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001771 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001772 const std::vector<sp<InputWindowHandle>> windowHandles =
1773 getWindowHandlesLocked(displayId);
1774 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001775 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001776 if (info->displayId == displayId &&
1777 windowHandle->getInfo()->layoutParamsType == InputWindowInfo::TYPE_WALLPAPER) {
1778 mTempTouchState
1779 .addOrUpdateWindow(windowHandle,
1780 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1781 InputTarget::
1782 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1783 InputTarget::FLAG_DISPATCH_AS_IS,
1784 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001785 }
1786 }
1787 }
1788 }
1789
1790 // Success! Output targets.
1791 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1792
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001793 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001794 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001795 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001796 }
1797
Michael Wright3dd60e22019-03-27 22:06:44 +00001798 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1799 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001800 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00001801 }
1802
Michael Wrightd02c5b62014-02-10 15:10:22 -08001803 // Drop the outside or hover touch windows since we will not care about them
1804 // in the next iteration.
1805 mTempTouchState.filterNonAsIsTouchWindows();
1806
1807Failed:
1808 // Check injection permission once and for all.
1809 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001810 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001811 injectionPermission = INJECTION_PERMISSION_GRANTED;
1812 } else {
1813 injectionPermission = INJECTION_PERMISSION_DENIED;
1814 }
1815 }
1816
1817 // Update final pieces of touch state if the injector had permission.
1818 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1819 if (!wrongDevice) {
1820 if (switchedDevice) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001821 if (DEBUG_FOCUS) {
1822 ALOGD("Conflicting pointer actions: Switched to a different device.");
1823 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001824 *outConflictingPointerActions = true;
1825 }
1826
1827 if (isHoverAction) {
1828 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001829 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001830 if (DEBUG_FOCUS) {
1831 ALOGD("Conflicting pointer actions: Hover received while pointer was "
1832 "down.");
1833 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001834 *outConflictingPointerActions = true;
1835 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001836 mTempTouchState.reset();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001837 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1838 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001839 mTempTouchState.deviceId = entry.deviceId;
1840 mTempTouchState.source = entry.source;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001841 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001842 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001843 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
1844 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001845 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001846 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001847 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1848 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001849 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001850 if (DEBUG_FOCUS) {
1851 ALOGD("Conflicting pointer actions: Down received while already down.");
1852 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001853 *outConflictingPointerActions = true;
1854 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001855 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1856 // One pointer went up.
1857 if (isSplit) {
1858 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001859 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001860
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001861 for (size_t i = 0; i < mTempTouchState.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001862 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001863 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1864 touchedWindow.pointerIds.clearBit(pointerId);
1865 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001866 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001867 continue;
1868 }
1869 }
1870 i += 1;
1871 }
1872 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001873 }
1874
1875 // Save changes unless the action was scroll in which case the temporary touch
1876 // state was only valid for this one action.
1877 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1878 if (mTempTouchState.displayId >= 0) {
1879 if (oldStateIndex >= 0) {
1880 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1881 } else {
1882 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1883 }
1884 } else if (oldStateIndex >= 0) {
1885 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1886 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001887 }
1888
1889 // Update hover state.
1890 mLastHoverWindowHandle = newHoverWindowHandle;
1891 }
1892 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001893 if (DEBUG_FOCUS) {
1894 ALOGD("Not updating touch focus because injection was denied.");
1895 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001896 }
1897
1898Unresponsive:
1899 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1900 mTempTouchState.reset();
1901
1902 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001903 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001904 if (DEBUG_FOCUS) {
1905 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1906 "timeSpentWaitingForApplication=%0.1fms",
1907 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1908 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001909 return injectionResult;
1910}
1911
1912void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001913 int32_t targetFlags, BitSet32 pointerIds,
1914 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001915 std::vector<InputTarget>::iterator it =
1916 std::find_if(inputTargets.begin(), inputTargets.end(),
1917 [&windowHandle](const InputTarget& inputTarget) {
1918 return inputTarget.inputChannel->getConnectionToken() ==
1919 windowHandle->getToken();
1920 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00001921
Chavi Weingarten114b77f2020-01-15 22:35:10 +00001922 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001923
1924 if (it == inputTargets.end()) {
1925 InputTarget inputTarget;
1926 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1927 if (inputChannel == nullptr) {
1928 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1929 return;
1930 }
1931 inputTarget.inputChannel = inputChannel;
1932 inputTarget.flags = targetFlags;
1933 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
1934 inputTargets.push_back(inputTarget);
1935 it = inputTargets.end() - 1;
1936 }
1937
1938 ALOG_ASSERT(it->flags == targetFlags);
1939 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
1940
1941 it->addPointers(pointerIds, -windowInfo->frameLeft, -windowInfo->frameTop,
1942 windowInfo->windowXScale, windowInfo->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001943}
1944
Michael Wright3dd60e22019-03-27 22:06:44 +00001945void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001946 int32_t displayId, float xOffset,
1947 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001948 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1949 mGlobalMonitorsByDisplay.find(displayId);
1950
1951 if (it != mGlobalMonitorsByDisplay.end()) {
1952 const std::vector<Monitor>& monitors = it->second;
1953 for (const Monitor& monitor : monitors) {
1954 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001955 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001956 }
1957}
1958
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001959void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
1960 float yOffset,
1961 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001962 InputTarget target;
1963 target.inputChannel = monitor.inputChannel;
1964 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001965 target.setDefaultPointerInfo(xOffset, yOffset, 1 /* windowXScale */, 1 /* windowYScale */);
Michael Wright3dd60e22019-03-27 22:06:44 +00001966 inputTargets.push_back(target);
1967}
1968
Michael Wrightd02c5b62014-02-10 15:10:22 -08001969bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001970 const InjectionState* injectionState) {
1971 if (injectionState &&
1972 (windowHandle == nullptr ||
1973 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
1974 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001975 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001976 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001977 "owned by uid %d",
1978 injectionState->injectorPid, injectionState->injectorUid,
1979 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001980 } else {
1981 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001982 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001983 }
1984 return false;
1985 }
1986 return true;
1987}
1988
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001989bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
1990 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001991 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001992 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1993 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001994 if (otherHandle == windowHandle) {
1995 break;
1996 }
1997
1998 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001999 if (otherInfo->displayId == displayId && otherInfo->visible &&
2000 !otherInfo->isTrustedOverlay() && otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002001 return true;
2002 }
2003 }
2004 return false;
2005}
2006
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002007bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2008 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002009 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002010 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002011 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002012 if (otherHandle == windowHandle) {
2013 break;
2014 }
2015
2016 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002017 if (otherInfo->displayId == displayId && otherInfo->visible &&
2018 !otherInfo->isTrustedOverlay() && otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002019 return true;
2020 }
2021 }
2022 return false;
2023}
2024
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002025std::string InputDispatcher::checkWindowReadyForMoreInputLocked(
2026 nsecs_t currentTime, const sp<InputWindowHandle>& windowHandle,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002027 const EventEntry& eventEntry, const char* targetType) {
Jeff Brownffb49772014-10-10 19:01:34 -07002028 // If the window is paused then keep waiting.
2029 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002030 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07002031 }
2032
2033 // If the window's connection is not registered then keep waiting.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07002034 sp<Connection> connection = getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002035 if (connection == nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002036 return StringPrintf("Waiting because the %s window's input channel is not "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002037 "registered with the input dispatcher. The window may be in the "
2038 "process of being removed.",
2039 targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07002040 }
2041
2042 // If the connection is dead then keep waiting.
Jeff Brownffb49772014-10-10 19:01:34 -07002043 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002044 return StringPrintf("Waiting because the %s window's input connection is %s."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002045 "The window may be in the process of being removed.",
2046 targetType, connection->getStatusLabel());
Jeff Brownffb49772014-10-10 19:01:34 -07002047 }
2048
2049 // If the connection is backed up then keep waiting.
2050 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002051 return StringPrintf("Waiting because the %s window's input channel is full. "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002052 "Outbound queue length: %zu. Wait queue length: %zu.",
2053 targetType, connection->outboundQueue.size(),
2054 connection->waitQueue.size());
Jeff Brownffb49772014-10-10 19:01:34 -07002055 }
2056
2057 // Ensure that the dispatch queues aren't too far backed up for this event.
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002058 if (eventEntry.type == EventEntry::Type::KEY) {
Jeff Brownffb49772014-10-10 19:01:34 -07002059 // If the event is a key event, then we must wait for all previous events to
2060 // complete before delivering it because previous events may have the
2061 // side-effect of transferring focus to a different window and we want to
2062 // ensure that the following keys are sent to the new window.
2063 //
2064 // Suppose the user touches a button in a window then immediately presses "A".
2065 // If the button causes a pop-up window to appear then we want to ensure that
2066 // the "A" key is delivered to the new pop-up window. This is because users
2067 // often anticipate pending UI changes when typing on a keyboard.
2068 // To obtain this behavior, we must serialize key events with respect to all
2069 // prior input events.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002070 if (!connection->outboundQueue.empty() || !connection->waitQueue.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002071 return StringPrintf("Waiting to send key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002072 "finished processing all of the input events that were previously "
2073 "delivered to it. Outbound queue length: %zu. Wait queue length: "
2074 "%zu.",
2075 targetType, connection->outboundQueue.size(),
2076 connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002077 }
Jeff Brownffb49772014-10-10 19:01:34 -07002078 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002079 // Touch events can always be sent to a window immediately because the user intended
2080 // to touch whatever was visible at the time. Even if focus changes or a new
2081 // window appears moments later, the touch event was meant to be delivered to
2082 // whatever window happened to be on screen at the time.
2083 //
2084 // Generic motion events, such as trackball or joystick events are a little trickier.
2085 // Like key events, generic motion events are delivered to the focused window.
2086 // Unlike key events, generic motion events don't tend to transfer focus to other
2087 // windows and it is not important for them to be serialized. So we prefer to deliver
2088 // generic motion events as soon as possible to improve efficiency and reduce lag
2089 // through batching.
2090 //
2091 // The one case where we pause input event delivery is when the wait queue is piling
2092 // up with lots of events because the application is not responding.
2093 // This condition ensures that ANRs are detected reliably.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002094 if (!connection->waitQueue.empty() &&
2095 currentTime >=
2096 connection->waitQueue.front()->deliveryTime + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002097 return StringPrintf("Waiting to send non-key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002098 "finished processing certain input events that were delivered to "
2099 "it over "
2100 "%0.1fms ago. Wait queue length: %zu. Wait queue head age: "
2101 "%0.1fms.",
2102 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
2103 connection->waitQueue.size(),
2104 (currentTime - connection->waitQueue.front()->deliveryTime) *
2105 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002106 }
2107 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002108 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002109}
2110
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002111std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002112 const sp<InputApplicationHandle>& applicationHandle,
2113 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002114 if (applicationHandle != nullptr) {
2115 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002116 std::string label(applicationHandle->getName());
2117 label += " - ";
2118 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002119 return label;
2120 } else {
2121 return applicationHandle->getName();
2122 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002123 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002124 return windowHandle->getName();
2125 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002126 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002127 }
2128}
2129
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002130void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002131 if (eventEntry.type == EventEntry::Type::FOCUS) {
2132 // Focus events are passed to apps, but do not represent user activity.
2133 return;
2134 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002135 int32_t displayId = getTargetDisplayId(eventEntry);
2136 sp<InputWindowHandle> focusedWindowHandle =
2137 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
2138 if (focusedWindowHandle != nullptr) {
2139 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002140 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
2141#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002142 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002143#endif
2144 return;
2145 }
2146 }
2147
2148 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002149 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002150 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002151 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2152 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002153 return;
2154 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002155
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002156 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002157 eventType = USER_ACTIVITY_EVENT_TOUCH;
2158 }
2159 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002160 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002161 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002162 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2163 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002164 return;
2165 }
2166 eventType = USER_ACTIVITY_EVENT_BUTTON;
2167 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002168 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002169 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002170 case EventEntry::Type::CONFIGURATION_CHANGED:
2171 case EventEntry::Type::DEVICE_RESET: {
2172 LOG_ALWAYS_FATAL("%s events are not user activity",
2173 EventEntry::typeToString(eventEntry.type));
2174 break;
2175 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002176 }
2177
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002178 std::unique_ptr<CommandEntry> commandEntry =
2179 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002180 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002181 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002182 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002183}
2184
2185void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002186 const sp<Connection>& connection,
2187 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002188 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002189 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002190 std::string message =
2191 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2192 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002193 ATRACE_NAME(message.c_str());
2194 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002195#if DEBUG_DISPATCH_CYCLE
2196 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002197 "globalScaleFactor=%f, pointerIds=0x%x %s",
2198 connection->getInputChannelName().c_str(), inputTarget.flags,
2199 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2200 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002201#endif
2202
2203 // Skip this event if the connection status is not normal.
2204 // We don't want to enqueue additional outbound events if the connection is broken.
2205 if (connection->status != Connection::STATUS_NORMAL) {
2206#if DEBUG_DISPATCH_CYCLE
2207 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002208 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002209#endif
2210 return;
2211 }
2212
2213 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002214 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2215 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2216 "Entry type %s should not have FLAG_SPLIT",
2217 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002218
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002219 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002220 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002221 MotionEntry* splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002222 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002223 if (!splitMotionEntry) {
2224 return; // split event was dropped
2225 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002226 if (DEBUG_FOCUS) {
2227 ALOGD("channel '%s' ~ Split motion event.",
2228 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002229 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002230 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002231 enqueueDispatchEntriesLocked(currentTime, connection, splitMotionEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002232 splitMotionEntry->release();
2233 return;
2234 }
2235 }
2236
2237 // Not splitting. Enqueue dispatch entries for the event as is.
2238 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2239}
2240
2241void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002242 const sp<Connection>& connection,
2243 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002244 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002245 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002246 std::string message =
2247 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32
2248 ")",
2249 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002250 ATRACE_NAME(message.c_str());
2251 }
2252
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002253 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002254
2255 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002256 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002257 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002258 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002259 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002260 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002261 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002262 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002263 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002264 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002265 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002266 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002267 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002268
2269 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002270 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002271 startDispatchCycleLocked(currentTime, connection);
2272 }
2273}
2274
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002275void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
2276 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002277 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002278 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002279 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002280 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2281 connection->getInputChannelName().c_str(),
2282 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002283 ATRACE_NAME(message.c_str());
2284 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002285 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002286 if (!(inputTargetFlags & dispatchMode)) {
2287 return;
2288 }
2289 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2290
2291 // This is a new event.
2292 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002293 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002294 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002295
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002296 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2297 // different EventEntry than what was passed in.
2298 EventEntry* newEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002299 // Apply target flags and update the connection's input state.
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002300 switch (newEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002301 case EventEntry::Type::KEY: {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002302 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*newEntry);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002303 dispatchEntry->resolvedAction = keyEntry.action;
2304 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002305
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002306 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2307 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002308#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002309 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2310 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002311#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002312 return; // skip the inconsistent event
2313 }
2314 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002315 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002316
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002317 case EventEntry::Type::MOTION: {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002318 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*newEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002319 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2320 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2321 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2322 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2323 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2324 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2325 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2326 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2327 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2328 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2329 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002330 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002331 }
2332 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002333 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2334 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002335#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002336 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2337 "event",
2338 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002339#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002340 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2341 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002342
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002343 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002344 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2345 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2346 }
2347 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2348 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2349 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002350
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002351 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2352 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002353#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002354 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2355 "event",
2356 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002357#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002358 return; // skip the inconsistent event
2359 }
2360
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002361 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002362 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002363
2364 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002365 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002366 case EventEntry::Type::FOCUS: {
2367 break;
2368 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002369 case EventEntry::Type::CONFIGURATION_CHANGED:
2370 case EventEntry::Type::DEVICE_RESET: {
2371 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002372 EventEntry::typeToString(newEntry->type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002373 break;
2374 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002375 }
2376
2377 // Remember that we are waiting for this dispatch to complete.
2378 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002379 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002380 }
2381
2382 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002383 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002384 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002385}
2386
chaviwfd6d3512019-03-25 13:23:49 -07002387void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002388 const sp<IBinder>& newToken) {
chaviw8c9cf542019-03-25 13:02:48 -07002389 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002390 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2391 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002392 return;
2393 }
2394
2395 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2396 if (inputWindowHandle == nullptr) {
2397 return;
2398 }
2399
chaviw8c9cf542019-03-25 13:02:48 -07002400 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002401 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002402
2403 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2404
2405 if (!hasFocusChanged) {
2406 return;
2407 }
2408
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002409 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2410 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002411 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002412 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002413}
2414
2415void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002416 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002417 if (ATRACE_ENABLED()) {
2418 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002419 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002420 ATRACE_NAME(message.c_str());
2421 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002422#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002423 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002424#endif
2425
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002426 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2427 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002428 dispatchEntry->deliveryTime = currentTime;
2429
2430 // Publish the event.
2431 status_t status;
2432 EventEntry* eventEntry = dispatchEntry->eventEntry;
2433 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002434 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002435 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002436
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002437 // Publish the key event.
2438 status = connection->inputPublisher
2439 .publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId,
2440 keyEntry->source, keyEntry->displayId,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06002441 INVALID_HMAC, dispatchEntry->resolvedAction,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002442 dispatchEntry->resolvedFlags, keyEntry->keyCode,
2443 keyEntry->scanCode, keyEntry->metaState,
2444 keyEntry->repeatCount, keyEntry->downTime,
2445 keyEntry->eventTime);
2446 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002447 }
2448
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002449 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002450 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002451
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002452 PointerCoords scaledCoords[MAX_POINTERS];
2453 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2454
chaviw82357092020-01-28 13:13:06 -08002455 // Set the X and Y offset and X and Y scale depending on the input source.
2456 float xOffset = 0.0f, yOffset = 0.0f;
2457 float xScale = 1.0f, yScale = 1.0f;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002458 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
2459 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2460 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002461 xScale = dispatchEntry->windowXScale;
2462 yScale = dispatchEntry->windowYScale;
2463 xOffset = dispatchEntry->xOffset * xScale;
2464 yOffset = dispatchEntry->yOffset * yScale;
2465 if (globalScaleFactor != 1.0f) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002466 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2467 scaledCoords[i] = motionEntry->pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002468 // Don't apply window scale here since we don't want scale to affect raw
2469 // coordinates. The scale will be sent back to the client and applied
2470 // later when requesting relative coordinates.
2471 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2472 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002473 }
2474 usingCoords = scaledCoords;
2475 }
2476 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002477 // We don't want the dispatch target to know.
2478 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
2479 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2480 scaledCoords[i].clear();
2481 }
2482 usingCoords = scaledCoords;
2483 }
2484 }
2485
2486 // Publish the motion event.
2487 status = connection->inputPublisher
2488 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2489 motionEntry->source, motionEntry->displayId,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06002490 INVALID_HMAC, dispatchEntry->resolvedAction,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002491 motionEntry->actionButton,
2492 dispatchEntry->resolvedFlags,
2493 motionEntry->edgeFlags, motionEntry->metaState,
2494 motionEntry->buttonState,
chaviw82357092020-01-28 13:13:06 -08002495 motionEntry->classification, xScale, yScale,
2496 xOffset, yOffset, motionEntry->xPrecision,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002497 motionEntry->yPrecision,
2498 motionEntry->xCursorPosition,
2499 motionEntry->yCursorPosition,
2500 motionEntry->downTime, motionEntry->eventTime,
2501 motionEntry->pointerCount,
2502 motionEntry->pointerProperties, usingCoords);
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05002503 reportTouchEventForStatistics(*motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002504 break;
2505 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002506 case EventEntry::Type::FOCUS: {
2507 FocusEntry* focusEntry = static_cast<FocusEntry*>(eventEntry);
2508 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
2509 focusEntry->hasFocus,
2510 mInTouchMode);
2511 break;
2512 }
2513
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002514 case EventEntry::Type::CONFIGURATION_CHANGED:
2515 case EventEntry::Type::DEVICE_RESET: {
2516 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
2517 EventEntry::typeToString(eventEntry->type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002518 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002519 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002520 }
2521
2522 // Check the result.
2523 if (status) {
2524 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002525 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002526 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002527 "This is unexpected because the wait queue is empty, so the pipe "
2528 "should be empty and we shouldn't have any problems writing an "
2529 "event to it, status=%d",
2530 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002531 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2532 } else {
2533 // Pipe is full and we are waiting for the app to finish process some events
2534 // before sending more events to it.
2535#if DEBUG_DISPATCH_CYCLE
2536 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002537 "waiting for the application to catch up",
2538 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002539#endif
2540 connection->inputPublisherBlocked = true;
2541 }
2542 } else {
2543 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002544 "status=%d",
2545 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002546 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2547 }
2548 return;
2549 }
2550
2551 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002552 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2553 connection->outboundQueue.end(),
2554 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002555 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002556 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002557 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002558 }
2559}
2560
2561void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002562 const sp<Connection>& connection, uint32_t seq,
2563 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002564#if DEBUG_DISPATCH_CYCLE
2565 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002566 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002567#endif
2568
2569 connection->inputPublisherBlocked = false;
2570
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002571 if (connection->status == Connection::STATUS_BROKEN ||
2572 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002573 return;
2574 }
2575
2576 // Notify other system components and prepare to start the next dispatch cycle.
2577 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2578}
2579
2580void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002581 const sp<Connection>& connection,
2582 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002583#if DEBUG_DISPATCH_CYCLE
2584 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002585 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002586#endif
2587
2588 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002589 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002590 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002591 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002592 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002593
2594 // The connection appears to be unrecoverably broken.
2595 // Ignore already broken or zombie connections.
2596 if (connection->status == Connection::STATUS_NORMAL) {
2597 connection->status = Connection::STATUS_BROKEN;
2598
2599 if (notify) {
2600 // Notify other system components.
2601 onDispatchCycleBrokenLocked(currentTime, connection);
2602 }
2603 }
2604}
2605
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002606void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2607 while (!queue.empty()) {
2608 DispatchEntry* dispatchEntry = queue.front();
2609 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002610 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002611 }
2612}
2613
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002614void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002615 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002616 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002617 }
2618 delete dispatchEntry;
2619}
2620
2621int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2622 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2623
2624 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002625 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002626
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002627 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002628 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002629 "fd=%d, events=0x%x",
2630 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002631 return 0; // remove the callback
2632 }
2633
2634 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002635 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002636 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2637 if (!(events & ALOOPER_EVENT_INPUT)) {
2638 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002639 "events=0x%x",
2640 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002641 return 1;
2642 }
2643
2644 nsecs_t currentTime = now();
2645 bool gotOne = false;
2646 status_t status;
2647 for (;;) {
2648 uint32_t seq;
2649 bool handled;
2650 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2651 if (status) {
2652 break;
2653 }
2654 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2655 gotOne = true;
2656 }
2657 if (gotOne) {
2658 d->runCommandsLockedInterruptible();
2659 if (status == WOULD_BLOCK) {
2660 return 1;
2661 }
2662 }
2663
2664 notify = status != DEAD_OBJECT || !connection->monitor;
2665 if (notify) {
2666 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002667 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002668 }
2669 } else {
2670 // Monitor channels are never explicitly unregistered.
2671 // We do it automatically when the remote endpoint is closed so don't warn
2672 // about them.
2673 notify = !connection->monitor;
2674 if (notify) {
2675 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002676 "events=0x%x",
2677 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002678 }
2679 }
2680
2681 // Unregister the channel.
2682 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2683 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002684 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08002685}
2686
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002687void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002688 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002689 for (const auto& pair : mConnectionsByFd) {
2690 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002691 }
2692}
2693
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002694void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002695 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002696 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2697 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2698}
2699
2700void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2701 const CancelationOptions& options,
2702 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2703 for (const auto& it : monitorsByDisplay) {
2704 const std::vector<Monitor>& monitors = it.second;
2705 for (const Monitor& monitor : monitors) {
2706 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002707 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002708 }
2709}
2710
Michael Wrightd02c5b62014-02-10 15:10:22 -08002711void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2712 const sp<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002713 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002714 if (connection == nullptr) {
2715 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002716 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002717
2718 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002719}
2720
2721void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2722 const sp<Connection>& connection, const CancelationOptions& options) {
2723 if (connection->status == Connection::STATUS_BROKEN) {
2724 return;
2725 }
2726
2727 nsecs_t currentTime = now();
2728
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07002729 std::vector<EventEntry*> cancelationEvents =
2730 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002731
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002732 if (cancelationEvents.empty()) {
2733 return;
2734 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002735#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002736 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
2737 "with reality: %s, mode=%d.",
2738 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
2739 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002740#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08002741
2742 InputTarget target;
2743 sp<InputWindowHandle> windowHandle =
2744 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
2745 if (windowHandle != nullptr) {
2746 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2747 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2748 windowInfo->windowXScale, windowInfo->windowYScale);
2749 target.globalScaleFactor = windowInfo->globalScaleFactor;
2750 }
2751 target.inputChannel = connection->inputChannel;
2752 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2753
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002754 for (size_t i = 0; i < cancelationEvents.size(); i++) {
2755 EventEntry* cancelationEventEntry = cancelationEvents[i];
2756 switch (cancelationEventEntry->type) {
2757 case EventEntry::Type::KEY: {
2758 logOutboundKeyDetails("cancel - ",
2759 static_cast<const KeyEntry&>(*cancelationEventEntry));
2760 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002761 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002762 case EventEntry::Type::MOTION: {
2763 logOutboundMotionDetails("cancel - ",
2764 static_cast<const MotionEntry&>(*cancelationEventEntry));
2765 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002766 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002767 case EventEntry::Type::FOCUS: {
2768 LOG_ALWAYS_FATAL("Canceling focus events is not supported");
2769 break;
2770 }
2771 case EventEntry::Type::CONFIGURATION_CHANGED:
2772 case EventEntry::Type::DEVICE_RESET: {
2773 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2774 EventEntry::typeToString(cancelationEventEntry->type));
2775 break;
2776 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002777 }
2778
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002779 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
2780 target, InputTarget::FLAG_DISPATCH_AS_IS);
2781
2782 cancelationEventEntry->release();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002783 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002784
2785 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002786}
2787
Svet Ganov5d3bc372020-01-26 23:11:07 -08002788void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
2789 const sp<Connection>& connection) {
2790 if (connection->status == Connection::STATUS_BROKEN) {
2791 return;
2792 }
2793
2794 nsecs_t currentTime = now();
2795
2796 std::vector<EventEntry*> downEvents =
2797 connection->inputState.synthesizePointerDownEvents(currentTime);
2798
2799 if (downEvents.empty()) {
2800 return;
2801 }
2802
2803#if DEBUG_OUTBOUND_EVENT_DETAILS
2804 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
2805 connection->getInputChannelName().c_str(), downEvents.size());
2806#endif
2807
2808 InputTarget target;
2809 sp<InputWindowHandle> windowHandle =
2810 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
2811 if (windowHandle != nullptr) {
2812 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2813 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2814 windowInfo->windowXScale, windowInfo->windowYScale);
2815 target.globalScaleFactor = windowInfo->globalScaleFactor;
2816 }
2817 target.inputChannel = connection->inputChannel;
2818 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2819
2820 for (EventEntry* downEventEntry : downEvents) {
2821 switch (downEventEntry->type) {
2822 case EventEntry::Type::MOTION: {
2823 logOutboundMotionDetails("down - ",
2824 static_cast<const MotionEntry&>(*downEventEntry));
2825 break;
2826 }
2827
2828 case EventEntry::Type::KEY:
2829 case EventEntry::Type::FOCUS:
2830 case EventEntry::Type::CONFIGURATION_CHANGED:
2831 case EventEntry::Type::DEVICE_RESET: {
2832 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2833 EventEntry::typeToString(downEventEntry->type));
2834 break;
2835 }
2836 }
2837
2838 enqueueDispatchEntryLocked(connection, downEventEntry, // increments ref
2839 target, InputTarget::FLAG_DISPATCH_AS_IS);
2840
2841 downEventEntry->release();
2842 }
2843
2844 startDispatchCycleLocked(currentTime, connection);
2845}
2846
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002847MotionEntry* InputDispatcher::splitMotionEvent(const MotionEntry& originalMotionEntry,
Garfield Tane84e6f92019-08-29 17:28:41 -07002848 BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002849 ALOG_ASSERT(pointerIds.value != 0);
2850
2851 uint32_t splitPointerIndexMap[MAX_POINTERS];
2852 PointerProperties splitPointerProperties[MAX_POINTERS];
2853 PointerCoords splitPointerCoords[MAX_POINTERS];
2854
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002855 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002856 uint32_t splitPointerCount = 0;
2857
2858 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002859 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002860 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002861 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002862 uint32_t pointerId = uint32_t(pointerProperties.id);
2863 if (pointerIds.hasBit(pointerId)) {
2864 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2865 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2866 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002867 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002868 splitPointerCount += 1;
2869 }
2870 }
2871
2872 if (splitPointerCount != pointerIds.count()) {
2873 // This is bad. We are missing some of the pointers that we expected to deliver.
2874 // Most likely this indicates that we received an ACTION_MOVE events that has
2875 // different pointer ids than we expected based on the previous ACTION_DOWN
2876 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2877 // in this way.
2878 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002879 "we expected there to be %d pointers. This probably means we received "
2880 "a broken sequence of pointer ids from the input device.",
2881 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002882 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002883 }
2884
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002885 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002886 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002887 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
2888 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002889 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2890 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002891 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002892 uint32_t pointerId = uint32_t(pointerProperties.id);
2893 if (pointerIds.hasBit(pointerId)) {
2894 if (pointerIds.count() == 1) {
2895 // The first/last pointer went down/up.
2896 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002897 ? AMOTION_EVENT_ACTION_DOWN
2898 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002899 } else {
2900 // A secondary pointer went down/up.
2901 uint32_t splitPointerIndex = 0;
2902 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2903 splitPointerIndex += 1;
2904 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002905 action = maskedAction |
2906 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002907 }
2908 } else {
2909 // An unrelated pointer changed.
2910 action = AMOTION_EVENT_ACTION_MOVE;
2911 }
2912 }
2913
Garfield Tan00f511d2019-06-12 16:55:40 -07002914 MotionEntry* splitMotionEntry =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002915 new MotionEntry(originalMotionEntry.sequenceNum, originalMotionEntry.eventTime,
2916 originalMotionEntry.deviceId, originalMotionEntry.source,
2917 originalMotionEntry.displayId, originalMotionEntry.policyFlags, action,
2918 originalMotionEntry.actionButton, originalMotionEntry.flags,
2919 originalMotionEntry.metaState, originalMotionEntry.buttonState,
2920 originalMotionEntry.classification, originalMotionEntry.edgeFlags,
2921 originalMotionEntry.xPrecision, originalMotionEntry.yPrecision,
2922 originalMotionEntry.xCursorPosition,
2923 originalMotionEntry.yCursorPosition, originalMotionEntry.downTime,
Garfield Tan00f511d2019-06-12 16:55:40 -07002924 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002925
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002926 if (originalMotionEntry.injectionState) {
2927 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002928 splitMotionEntry->injectionState->refCount += 1;
2929 }
2930
2931 return splitMotionEntry;
2932}
2933
2934void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2935#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002936 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002937#endif
2938
2939 bool needWake;
2940 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002941 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002942
Prabir Pradhan42611e02018-11-27 14:04:02 -08002943 ConfigurationChangedEntry* newEntry =
2944 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002945 needWake = enqueueInboundEventLocked(newEntry);
2946 } // release lock
2947
2948 if (needWake) {
2949 mLooper->wake();
2950 }
2951}
2952
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002953/**
2954 * If one of the meta shortcuts is detected, process them here:
2955 * Meta + Backspace -> generate BACK
2956 * Meta + Enter -> generate HOME
2957 * This will potentially overwrite keyCode and metaState.
2958 */
2959void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002960 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002961 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2962 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2963 if (keyCode == AKEYCODE_DEL) {
2964 newKeyCode = AKEYCODE_BACK;
2965 } else if (keyCode == AKEYCODE_ENTER) {
2966 newKeyCode = AKEYCODE_HOME;
2967 }
2968 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002969 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002970 struct KeyReplacement replacement = {keyCode, deviceId};
2971 mReplacedKeys.add(replacement, newKeyCode);
2972 keyCode = newKeyCode;
2973 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2974 }
2975 } else if (action == AKEY_EVENT_ACTION_UP) {
2976 // In order to maintain a consistent stream of up and down events, check to see if the key
2977 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2978 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002979 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002980 struct KeyReplacement replacement = {keyCode, deviceId};
2981 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2982 if (index >= 0) {
2983 keyCode = mReplacedKeys.valueAt(index);
2984 mReplacedKeys.removeItemsAt(index);
2985 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2986 }
2987 }
2988}
2989
Michael Wrightd02c5b62014-02-10 15:10:22 -08002990void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2991#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002992 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
2993 "policyFlags=0x%x, action=0x%x, "
2994 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
2995 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2996 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
2997 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002998#endif
2999 if (!validateKeyEvent(args->action)) {
3000 return;
3001 }
3002
3003 uint32_t policyFlags = args->policyFlags;
3004 int32_t flags = args->flags;
3005 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003006 // InputDispatcher tracks and generates key repeats on behalf of
3007 // whatever notifies it, so repeatCount should always be set to 0
3008 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003009 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3010 policyFlags |= POLICY_FLAG_VIRTUAL;
3011 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3012 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003013 if (policyFlags & POLICY_FLAG_FUNCTION) {
3014 metaState |= AMETA_FUNCTION_ON;
3015 }
3016
3017 policyFlags |= POLICY_FLAG_TRUSTED;
3018
Michael Wright78f24442014-08-06 15:55:28 -07003019 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003020 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003021
Michael Wrightd02c5b62014-02-10 15:10:22 -08003022 KeyEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06003023 event.initialize(args->deviceId, args->source, args->displayId, INVALID_HMAC, args->action,
3024 flags, keyCode, args->scanCode, metaState, repeatCount, args->downTime,
3025 args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003026
Michael Wright2b3c3302018-03-02 17:19:13 +00003027 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003028 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003029 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3030 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003031 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003032 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003033
Michael Wrightd02c5b62014-02-10 15:10:22 -08003034 bool needWake;
3035 { // acquire lock
3036 mLock.lock();
3037
3038 if (shouldSendKeyToInputFilterLocked(args)) {
3039 mLock.unlock();
3040
3041 policyFlags |= POLICY_FLAG_FILTERED;
3042 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3043 return; // event was consumed by the filter
3044 }
3045
3046 mLock.lock();
3047 }
3048
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003049 KeyEntry* newEntry =
3050 new KeyEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
3051 args->displayId, policyFlags, args->action, flags, keyCode,
3052 args->scanCode, metaState, repeatCount, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003053
3054 needWake = enqueueInboundEventLocked(newEntry);
3055 mLock.unlock();
3056 } // release lock
3057
3058 if (needWake) {
3059 mLooper->wake();
3060 }
3061}
3062
3063bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3064 return mInputFilterEnabled;
3065}
3066
3067void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3068#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08003069 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07003070 ", policyFlags=0x%x, "
3071 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3072 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003073 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07003074 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3075 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
Jaewan Kim372fbe42019-10-02 10:58:46 +09003076 args->edgeFlags, args->xPrecision, args->yPrecision, args->xCursorPosition,
Garfield Tan00f511d2019-06-12 16:55:40 -07003077 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003078 for (uint32_t i = 0; i < args->pointerCount; i++) {
3079 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003080 "x=%f, y=%f, pressure=%f, size=%f, "
3081 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3082 "orientation=%f",
3083 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3084 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3085 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3086 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3087 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3088 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3089 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3090 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3091 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3092 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003093 }
3094#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003095 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3096 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003097 return;
3098 }
3099
3100 uint32_t policyFlags = args->policyFlags;
3101 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003102
3103 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003104 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003105 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3106 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003107 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003108 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003109
3110 bool needWake;
3111 { // acquire lock
3112 mLock.lock();
3113
3114 if (shouldSendMotionToInputFilterLocked(args)) {
3115 mLock.unlock();
3116
3117 MotionEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06003118 event.initialize(args->deviceId, args->source, args->displayId, INVALID_HMAC,
3119 args->action, args->actionButton, args->flags, args->edgeFlags,
3120 args->metaState, args->buttonState, args->classification, 1 /*xScale*/,
3121 1 /*yScale*/, 0 /* xOffset */, 0 /* yOffset */, args->xPrecision,
Garfield Tan00f511d2019-06-12 16:55:40 -07003122 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3123 args->downTime, args->eventTime, args->pointerCount,
3124 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003125
3126 policyFlags |= POLICY_FLAG_FILTERED;
3127 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3128 return; // event was consumed by the filter
3129 }
3130
3131 mLock.lock();
3132 }
3133
3134 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07003135 MotionEntry* newEntry =
3136 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
3137 args->displayId, policyFlags, args->action, args->actionButton,
3138 args->flags, args->metaState, args->buttonState,
3139 args->classification, args->edgeFlags, args->xPrecision,
3140 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3141 args->downTime, args->pointerCount, args->pointerProperties,
3142 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003143
3144 needWake = enqueueInboundEventLocked(newEntry);
3145 mLock.unlock();
3146 } // release lock
3147
3148 if (needWake) {
3149 mLooper->wake();
3150 }
3151}
3152
3153bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003154 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003155}
3156
3157void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3158#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003159 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003160 "switchMask=0x%08x",
3161 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003162#endif
3163
3164 uint32_t policyFlags = args->policyFlags;
3165 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003166 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003167}
3168
3169void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3170#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003171 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3172 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003173#endif
3174
3175 bool needWake;
3176 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003177 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003178
Prabir Pradhan42611e02018-11-27 14:04:02 -08003179 DeviceResetEntry* newEntry =
3180 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003181 needWake = enqueueInboundEventLocked(newEntry);
3182 } // release lock
3183
3184 if (needWake) {
3185 mLooper->wake();
3186 }
3187}
3188
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003189int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid,
3190 int32_t injectorUid, int32_t syncMode,
3191 int32_t timeoutMillis, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003192#if DEBUG_INBOUND_EVENT_DETAILS
3193 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003194 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
3195 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003196#endif
3197
3198 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
3199
3200 policyFlags |= POLICY_FLAG_INJECTED;
3201 if (hasInjectionPermission(injectorPid, injectorUid)) {
3202 policyFlags |= POLICY_FLAG_TRUSTED;
3203 }
3204
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003205 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003206 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003207 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003208 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3209 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003210 if (!validateKeyEvent(action)) {
3211 return INPUT_EVENT_INJECTION_FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003212 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003213
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003214 int32_t flags = incomingKey.getFlags();
3215 int32_t keyCode = incomingKey.getKeyCode();
3216 int32_t metaState = incomingKey.getMetaState();
3217 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003218 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003219 KeyEvent keyEvent;
3220 keyEvent.initialize(VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3221 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3222 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3223 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003224
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003225 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3226 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003227 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003228
3229 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3230 android::base::Timer t;
3231 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3232 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3233 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3234 std::to_string(t.duration().count()).c_str());
3235 }
3236 }
3237
3238 mLock.lock();
3239 KeyEntry* injectedEntry =
3240 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003241 VIRTUAL_KEYBOARD_ID, keyEvent.getSource(), keyEvent.getDisplayId(),
3242 policyFlags, action, flags, keyEvent.getKeyCode(),
3243 keyEvent.getScanCode(), keyEvent.getMetaState(),
3244 keyEvent.getRepeatCount(), keyEvent.getDownTime());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003245 injectedEntries.push(injectedEntry);
3246 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003247 }
3248
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003249 case AINPUT_EVENT_TYPE_MOTION: {
3250 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3251 int32_t action = motionEvent->getAction();
3252 size_t pointerCount = motionEvent->getPointerCount();
3253 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3254 int32_t actionButton = motionEvent->getActionButton();
3255 int32_t displayId = motionEvent->getDisplayId();
3256 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
3257 return INPUT_EVENT_INJECTION_FAILED;
3258 }
3259
3260 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3261 nsecs_t eventTime = motionEvent->getEventTime();
3262 android::base::Timer t;
3263 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3264 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3265 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3266 std::to_string(t.duration().count()).c_str());
3267 }
3268 }
3269
3270 mLock.lock();
3271 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3272 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
3273 MotionEntry* injectedEntry =
Garfield Tan00f511d2019-06-12 16:55:40 -07003274 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003275 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
Garfield Tan00f511d2019-06-12 16:55:40 -07003276 motionEvent->getDisplayId(), policyFlags, action, actionButton,
3277 motionEvent->getFlags(), motionEvent->getMetaState(),
3278 motionEvent->getButtonState(), motionEvent->getClassification(),
3279 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3280 motionEvent->getYPrecision(),
3281 motionEvent->getRawXCursorPosition(),
3282 motionEvent->getRawYCursorPosition(),
3283 motionEvent->getDownTime(), uint32_t(pointerCount),
3284 pointerProperties, samplePointerCoords,
3285 motionEvent->getXOffset(), motionEvent->getYOffset());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003286 injectedEntries.push(injectedEntry);
3287 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3288 sampleEventTimes += 1;
3289 samplePointerCoords += pointerCount;
3290 MotionEntry* nextInjectedEntry =
3291 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003292 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003293 motionEvent->getDisplayId(), policyFlags, action,
3294 actionButton, motionEvent->getFlags(),
3295 motionEvent->getMetaState(), motionEvent->getButtonState(),
3296 motionEvent->getClassification(),
3297 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3298 motionEvent->getYPrecision(),
3299 motionEvent->getRawXCursorPosition(),
3300 motionEvent->getRawYCursorPosition(),
3301 motionEvent->getDownTime(), uint32_t(pointerCount),
3302 pointerProperties, samplePointerCoords,
3303 motionEvent->getXOffset(), motionEvent->getYOffset());
3304 injectedEntries.push(nextInjectedEntry);
3305 }
3306 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003307 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003308
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003309 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003310 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003311 return INPUT_EVENT_INJECTION_FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003312 }
3313
3314 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3315 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3316 injectionState->injectionIsAsync = true;
3317 }
3318
3319 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003320 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003321
3322 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003323 while (!injectedEntries.empty()) {
3324 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3325 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003326 }
3327
3328 mLock.unlock();
3329
3330 if (needWake) {
3331 mLooper->wake();
3332 }
3333
3334 int32_t injectionResult;
3335 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003336 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003337
3338 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3339 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3340 } else {
3341 for (;;) {
3342 injectionResult = injectionState->injectionResult;
3343 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3344 break;
3345 }
3346
3347 nsecs_t remainingTimeout = endTime - now();
3348 if (remainingTimeout <= 0) {
3349#if DEBUG_INJECTION
3350 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003351 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003352#endif
3353 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3354 break;
3355 }
3356
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003357 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003358 }
3359
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003360 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED &&
3361 syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003362 while (injectionState->pendingForegroundDispatches != 0) {
3363#if DEBUG_INJECTION
3364 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003365 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003366#endif
3367 nsecs_t remainingTimeout = endTime - now();
3368 if (remainingTimeout <= 0) {
3369#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003370 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3371 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003372#endif
3373 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3374 break;
3375 }
3376
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003377 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003378 }
3379 }
3380 }
3381
3382 injectionState->release();
3383 } // release lock
3384
3385#if DEBUG_INJECTION
3386 ALOGD("injectInputEvent - Finished with result %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003387 "injectorPid=%d, injectorUid=%d",
3388 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003389#endif
3390
3391 return injectionResult;
3392}
3393
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003394std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
3395 return nullptr;
3396}
3397
Michael Wrightd02c5b62014-02-10 15:10:22 -08003398bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003399 return injectorUid == 0 ||
3400 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003401}
3402
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003403void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003404 InjectionState* injectionState = entry->injectionState;
3405 if (injectionState) {
3406#if DEBUG_INJECTION
3407 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003408 "injectorPid=%d, injectorUid=%d",
3409 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003410#endif
3411
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003412 if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003413 // Log the outcome since the injector did not wait for the injection result.
3414 switch (injectionResult) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003415 case INPUT_EVENT_INJECTION_SUCCEEDED:
3416 ALOGV("Asynchronous input event injection succeeded.");
3417 break;
3418 case INPUT_EVENT_INJECTION_FAILED:
3419 ALOGW("Asynchronous input event injection failed.");
3420 break;
3421 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3422 ALOGW("Asynchronous input event injection permission denied.");
3423 break;
3424 case INPUT_EVENT_INJECTION_TIMED_OUT:
3425 ALOGW("Asynchronous input event injection timed out.");
3426 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003427 }
3428 }
3429
3430 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003431 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003432 }
3433}
3434
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003435void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003436 InjectionState* injectionState = entry->injectionState;
3437 if (injectionState) {
3438 injectionState->pendingForegroundDispatches += 1;
3439 }
3440}
3441
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003442void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003443 InjectionState* injectionState = entry->injectionState;
3444 if (injectionState) {
3445 injectionState->pendingForegroundDispatches -= 1;
3446
3447 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003448 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003449 }
3450 }
3451}
3452
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003453std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3454 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003455 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003456}
3457
Michael Wrightd02c5b62014-02-10 15:10:22 -08003458sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003459 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003460 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003461 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3462 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003463 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003464 return windowHandle;
3465 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003466 }
3467 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003468 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003469}
3470
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003471bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003472 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003473 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3474 for (const sp<InputWindowHandle>& handle : windowHandles) {
3475 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003476 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003477 ALOGE("Found window %s in display %" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003478 ", but it should belong to display %" PRId32,
3479 windowHandle->getName().c_str(), it.first,
3480 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003481 }
3482 return true;
3483 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003484 }
3485 }
3486 return false;
3487}
3488
Robert Carr5c8a0262018-10-03 16:30:44 -07003489sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3490 size_t count = mInputChannelsByToken.count(token);
3491 if (count == 0) {
3492 return nullptr;
3493 }
3494 return mInputChannelsByToken.at(token);
3495}
3496
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003497void InputDispatcher::updateWindowHandlesForDisplayLocked(
3498 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3499 if (inputWindowHandles.empty()) {
3500 // Remove all handles on a display if there are no windows left.
3501 mWindowHandlesByDisplay.erase(displayId);
3502 return;
3503 }
3504
3505 // Since we compare the pointer of input window handles across window updates, we need
3506 // to make sure the handle object for the same window stays unchanged across updates.
3507 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003508 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003509 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003510 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003511 }
3512
3513 std::vector<sp<InputWindowHandle>> newHandles;
3514 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3515 if (!handle->updateInfo()) {
3516 // handle no longer valid
3517 continue;
3518 }
3519
3520 const InputWindowInfo* info = handle->getInfo();
3521 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3522 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3523 const bool noInputChannel =
3524 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3525 const bool canReceiveInput =
3526 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3527 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3528 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003529 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003530 handle->getName().c_str());
3531 }
3532 continue;
3533 }
3534
3535 if (info->displayId != displayId) {
3536 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3537 handle->getName().c_str(), displayId, info->displayId);
3538 continue;
3539 }
3540
chaviwaf87b3e2019-10-01 16:59:28 -07003541 if (oldHandlesById.find(handle->getId()) != oldHandlesById.end()) {
3542 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003543 oldHandle->updateFrom(handle);
3544 newHandles.push_back(oldHandle);
3545 } else {
3546 newHandles.push_back(handle);
3547 }
3548 }
3549
3550 // Insert or replace
3551 mWindowHandlesByDisplay[displayId] = newHandles;
3552}
3553
Arthur Hungb92218b2018-08-14 12:00:21 +08003554/**
3555 * Called from InputManagerService, update window handle list by displayId that can receive input.
3556 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3557 * If set an empty list, remove all handles from the specific display.
3558 * For focused handle, check if need to change and send a cancel event to previous one.
3559 * For removed handle, check if need to send a cancel event if already in touch.
3560 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003561void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003562 int32_t displayId,
3563 const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003564 if (DEBUG_FOCUS) {
3565 std::string windowList;
3566 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
3567 windowList += iwh->getName() + " ";
3568 }
3569 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
3570 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003571 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003572 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003573
Arthur Hungb92218b2018-08-14 12:00:21 +08003574 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003575 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3576 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003577
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003578 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3579
Tiger Huang721e26f2018-07-24 22:26:19 +08003580 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003581 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003582 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3583 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3584 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3585 windowHandle->getInfo()->visible) {
3586 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003587 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003588 if (windowHandle == mLastHoverWindowHandle) {
3589 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003590 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003591 }
3592
3593 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003594 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003595 }
3596
Tiger Huang721e26f2018-07-24 22:26:19 +08003597 sp<InputWindowHandle> oldFocusedWindowHandle =
3598 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3599
chaviwaf87b3e2019-10-01 16:59:28 -07003600 if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003601 if (oldFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003602 if (DEBUG_FOCUS) {
3603 ALOGD("Focus left window: %s in display %" PRId32,
3604 oldFocusedWindowHandle->getName().c_str(), displayId);
3605 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003606 sp<InputChannel> focusedInputChannel =
3607 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003608 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003609 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003610 "focus left window");
3611 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003612 enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003613 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003614 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003615 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003616 if (newFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003617 if (DEBUG_FOCUS) {
3618 ALOGD("Focus entered window: %s in display %" PRId32,
3619 newFocusedWindowHandle->getName().c_str(), displayId);
3620 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003621 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003622 enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003623 }
Robert Carrf759f162018-11-13 12:57:11 -08003624
3625 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003626 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003627 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003628 }
3629
Arthur Hungb92218b2018-08-14 12:00:21 +08003630 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3631 if (stateIndex >= 0) {
3632 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003633 for (size_t i = 0; i < state.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003634 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003635 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003636 if (DEBUG_FOCUS) {
3637 ALOGD("Touched window was removed: %s in display %" PRId32,
3638 touchedWindow.windowHandle->getName().c_str(), displayId);
3639 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003640 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003641 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003642 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003643 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003644 "touched window was removed");
3645 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
3646 options);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003647 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003648 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003649 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003650 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003651 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003652 }
3653 }
3654
3655 // Release information for windows that are no longer present.
3656 // This ensures that unused input channels are released promptly.
3657 // Otherwise, they might stick around until the window handle is destroyed
3658 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003659 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003660 if (!hasWindowHandleLocked(oldWindowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003661 if (DEBUG_FOCUS) {
3662 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
3663 }
Arthur Hung3b413f22018-10-26 18:05:34 +08003664 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003665 }
3666 }
3667 } // release lock
3668
3669 // Wake up poll loop since it may need to make new input dispatching choices.
3670 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003671
3672 if (setInputWindowsListener) {
3673 setInputWindowsListener->onSetInputWindowsFinished();
3674 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003675}
3676
3677void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003678 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003679 if (DEBUG_FOCUS) {
3680 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
3681 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
3682 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003683 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003684 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003685
Tiger Huang721e26f2018-07-24 22:26:19 +08003686 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3687 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003688 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003689 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3690 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003691 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003692 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003693 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003694 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003695 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003696 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003697 oldFocusedApplicationHandle.clear();
3698 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003699 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003700 } // release lock
3701
3702 // Wake up poll loop since it may need to make new input dispatching choices.
3703 mLooper->wake();
3704}
3705
Tiger Huang721e26f2018-07-24 22:26:19 +08003706/**
3707 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3708 * the display not specified.
3709 *
3710 * We track any unreleased events for each window. If a window loses the ability to receive the
3711 * released event, we will send a cancel event to it. So when the focused display is changed, we
3712 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3713 * display. The display-specified events won't be affected.
3714 */
3715void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003716 if (DEBUG_FOCUS) {
3717 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3718 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003719 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003720 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003721
3722 if (mFocusedDisplayId != displayId) {
3723 sp<InputWindowHandle> oldFocusedWindowHandle =
3724 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3725 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003726 sp<InputChannel> inputChannel =
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003727 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003728 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003729 CancelationOptions
3730 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3731 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003732 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003733 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3734 }
3735 }
3736 mFocusedDisplayId = displayId;
3737
3738 // Sanity check
3739 sp<InputWindowHandle> newFocusedWindowHandle =
3740 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003741 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003742
Tiger Huang721e26f2018-07-24 22:26:19 +08003743 if (newFocusedWindowHandle == nullptr) {
3744 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3745 if (!mFocusedWindowHandlesByDisplay.empty()) {
3746 ALOGE("But another display has a focused window:");
3747 for (auto& it : mFocusedWindowHandlesByDisplay) {
3748 const int32_t displayId = it.first;
3749 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003750 ALOGE("Display #%" PRId32 " has focused window: '%s'\n", displayId,
3751 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003752 }
3753 }
3754 }
3755 }
3756
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003757 if (DEBUG_FOCUS) {
3758 logDispatchStateLocked();
3759 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003760 } // release lock
3761
3762 // Wake up poll loop since it may need to make new input dispatching choices.
3763 mLooper->wake();
3764}
3765
Michael Wrightd02c5b62014-02-10 15:10:22 -08003766void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003767 if (DEBUG_FOCUS) {
3768 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3769 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003770
3771 bool changed;
3772 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003773 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003774
3775 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3776 if (mDispatchFrozen && !frozen) {
3777 resetANRTimeoutsLocked();
3778 }
3779
3780 if (mDispatchEnabled && !enabled) {
3781 resetAndDropEverythingLocked("dispatcher is being disabled");
3782 }
3783
3784 mDispatchEnabled = enabled;
3785 mDispatchFrozen = frozen;
3786 changed = true;
3787 } else {
3788 changed = false;
3789 }
3790
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003791 if (DEBUG_FOCUS) {
3792 logDispatchStateLocked();
3793 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003794 } // release lock
3795
3796 if (changed) {
3797 // Wake up poll loop since it may need to make new input dispatching choices.
3798 mLooper->wake();
3799 }
3800}
3801
3802void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003803 if (DEBUG_FOCUS) {
3804 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3805 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003806
3807 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003808 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003809
3810 if (mInputFilterEnabled == enabled) {
3811 return;
3812 }
3813
3814 mInputFilterEnabled = enabled;
3815 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3816 } // release lock
3817
3818 // Wake up poll loop since there might be work to do to drop everything.
3819 mLooper->wake();
3820}
3821
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08003822void InputDispatcher::setInTouchMode(bool inTouchMode) {
3823 std::scoped_lock lock(mLock);
3824 mInTouchMode = inTouchMode;
3825}
3826
chaviwfbe5d9c2018-12-26 12:23:37 -08003827bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3828 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003829 if (DEBUG_FOCUS) {
3830 ALOGD("Trivial transfer to same window.");
3831 }
chaviwfbe5d9c2018-12-26 12:23:37 -08003832 return true;
3833 }
3834
Michael Wrightd02c5b62014-02-10 15:10:22 -08003835 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003836 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003837
chaviwfbe5d9c2018-12-26 12:23:37 -08003838 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3839 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003840 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003841 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003842 return false;
3843 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003844 if (DEBUG_FOCUS) {
3845 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3846 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3847 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003849 if (DEBUG_FOCUS) {
3850 ALOGD("Cannot transfer focus because windows are on different displays.");
3851 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003852 return false;
3853 }
3854
3855 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003856 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3857 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3858 for (size_t i = 0; i < state.windows.size(); i++) {
3859 const TouchedWindow& touchedWindow = state.windows[i];
3860 if (touchedWindow.windowHandle == fromWindowHandle) {
3861 int32_t oldTargetFlags = touchedWindow.targetFlags;
3862 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003863
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003864 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003866 int32_t newTargetFlags = oldTargetFlags &
3867 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
3868 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003869 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003870
Jeff Brownf086ddb2014-02-11 14:28:48 -08003871 found = true;
3872 goto Found;
3873 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003874 }
3875 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003876 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003877
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003878 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003879 if (DEBUG_FOCUS) {
3880 ALOGD("Focus transfer failed because from window did not have focus.");
3881 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003882 return false;
3883 }
3884
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07003885 sp<Connection> fromConnection = getConnectionLocked(fromToken);
3886 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003887 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003888 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003889 CancelationOptions
3890 options(CancelationOptions::CANCEL_POINTER_EVENTS,
3891 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003892 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003893 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003894 }
3895
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003896 if (DEBUG_FOCUS) {
3897 logDispatchStateLocked();
3898 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003899 } // release lock
3900
3901 // Wake up poll loop since it may need to make new input dispatching choices.
3902 mLooper->wake();
3903 return true;
3904}
3905
3906void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003907 if (DEBUG_FOCUS) {
3908 ALOGD("Resetting and dropping all events (%s).", reason);
3909 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003910
3911 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3912 synthesizeCancelationEventsForAllConnectionsLocked(options);
3913
3914 resetKeyRepeatLocked();
3915 releasePendingEventLocked();
3916 drainInboundQueueLocked();
3917 resetANRTimeoutsLocked();
3918
Jeff Brownf086ddb2014-02-11 14:28:48 -08003919 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003920 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003921 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003922}
3923
3924void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003925 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003926 dumpDispatchStateLocked(dump);
3927
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003928 std::istringstream stream(dump);
3929 std::string line;
3930
3931 while (std::getline(stream, line, '\n')) {
3932 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003933 }
3934}
3935
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003936void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003937 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3938 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3939 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003940 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003941
Tiger Huang721e26f2018-07-24 22:26:19 +08003942 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3943 dump += StringPrintf(INDENT "FocusedApplications:\n");
3944 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3945 const int32_t displayId = it.first;
3946 const sp<InputApplicationHandle>& applicationHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003947 dump += StringPrintf(INDENT2 "displayId=%" PRId32
3948 ", name='%s', dispatchingTimeout=%0.3fms\n",
3949 displayId, applicationHandle->getName().c_str(),
3950 applicationHandle->getDispatchingTimeout(
3951 DEFAULT_INPUT_DISPATCHING_TIMEOUT) /
3952 1000000.0);
Tiger Huang721e26f2018-07-24 22:26:19 +08003953 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003954 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003955 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003956 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003957
3958 if (!mFocusedWindowHandlesByDisplay.empty()) {
3959 dump += StringPrintf(INDENT "FocusedWindows:\n");
3960 for (auto& it : mFocusedWindowHandlesByDisplay) {
3961 const int32_t displayId = it.first;
3962 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003963 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
3964 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003965 }
3966 } else {
3967 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3968 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003969
Jeff Brownf086ddb2014-02-11 14:28:48 -08003970 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003971 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003972 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3973 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003974 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003975 state.displayId, toString(state.down), toString(state.split),
3976 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003977 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003978 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003979 for (size_t i = 0; i < state.windows.size(); i++) {
3980 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003981 dump += StringPrintf(INDENT4
3982 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3983 i, touchedWindow.windowHandle->getName().c_str(),
3984 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003985 }
3986 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003987 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003988 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003989 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003990 dump += INDENT3 "Portal windows:\n";
3991 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003992 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003993 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
3994 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003995 }
3996 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003997 }
3998 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003999 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004000 }
4001
Arthur Hungb92218b2018-08-14 12:00:21 +08004002 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004003 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004004 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004005 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004006 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004007 dump += INDENT2 "Windows:\n";
4008 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004009 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004010 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004011
Arthur Hungb92218b2018-08-14 12:00:21 +08004012 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004013 "portalToDisplayId=%d, paused=%s, hasFocus=%s, "
chaviwcb923212019-12-30 14:05:11 -08004014 "hasWallpaper=%s, visible=%s, canReceiveKeys=%s, "
4015 "flags=0x%08x, type=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004016 "frame=[%d,%d][%d,%d], globalScale=%f, "
chaviwcb923212019-12-30 14:05:11 -08004017 "windowScale=(%f,%f), touchableRegion=",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004018 i, windowInfo->name.c_str(), windowInfo->displayId,
4019 windowInfo->portalToDisplayId,
4020 toString(windowInfo->paused),
4021 toString(windowInfo->hasFocus),
4022 toString(windowInfo->hasWallpaper),
4023 toString(windowInfo->visible),
4024 toString(windowInfo->canReceiveKeys),
4025 windowInfo->layoutParamsFlags,
chaviwcb923212019-12-30 14:05:11 -08004026 windowInfo->layoutParamsType, windowInfo->frameLeft,
4027 windowInfo->frameTop, windowInfo->frameRight,
4028 windowInfo->frameBottom, windowInfo->globalScaleFactor,
4029 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08004030 dumpRegion(dump, windowInfo->touchableRegion);
4031 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
4032 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004033 windowInfo->ownerPid, windowInfo->ownerUid,
4034 windowInfo->dispatchingTimeout / 1000000.0);
Arthur Hungb92218b2018-08-14 12:00:21 +08004035 }
4036 } else {
4037 dump += INDENT2 "Windows: <none>\n";
4038 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004039 }
4040 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004041 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004042 }
4043
Michael Wright3dd60e22019-03-27 22:06:44 +00004044 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004045 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004046 const std::vector<Monitor>& monitors = it.second;
4047 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4048 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004049 }
4050 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004051 const std::vector<Monitor>& monitors = it.second;
4052 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4053 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004054 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004055 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004056 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004057 }
4058
4059 nsecs_t currentTime = now();
4060
4061 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004062 if (!mRecentQueue.empty()) {
4063 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
4064 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004065 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004066 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004067 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004068 }
4069 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004070 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004071 }
4072
4073 // Dump event currently being dispatched.
4074 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004075 dump += INDENT "PendingEvent:\n";
4076 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004077 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004078 dump += StringPrintf(", age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004079 (currentTime - mPendingEvent->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004080 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004081 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004082 }
4083
4084 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004085 if (!mInboundQueue.empty()) {
4086 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
4087 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004088 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004089 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004090 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004091 }
4092 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004093 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004094 }
4095
Michael Wright78f24442014-08-06 15:55:28 -07004096 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004097 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07004098 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
4099 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
4100 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004101 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n", i,
4102 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004103 }
4104 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004105 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004106 }
4107
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004108 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004109 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004110 for (const auto& pair : mConnectionsByFd) {
4111 const sp<Connection>& connection = pair.second;
4112 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
4113 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
4114 pair.first, connection->getInputChannelName().c_str(),
4115 connection->getWindowName().c_str(), connection->getStatusLabel(),
4116 toString(connection->monitor),
4117 toString(connection->inputPublisherBlocked));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004118
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004119 if (!connection->outboundQueue.empty()) {
4120 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4121 connection->outboundQueue.size());
4122 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004123 dump.append(INDENT4);
4124 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004125 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004126 entry->targetFlags, entry->resolvedAction,
4127 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004128 }
4129 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004130 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004131 }
4132
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004133 if (!connection->waitQueue.empty()) {
4134 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4135 connection->waitQueue.size());
4136 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004137 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004138 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004139 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004140 "age=%0.1fms, wait=%0.1fms\n",
4141 entry->targetFlags, entry->resolvedAction,
4142 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
4143 (currentTime - entry->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004144 }
4145 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004146 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004147 }
4148 }
4149 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004150 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004151 }
4152
4153 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004154 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004155 (mAppSwitchDueTime - now()) / 1000000.0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004156 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004157 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004158 }
4159
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004160 dump += INDENT "Configuration:\n";
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004161 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004162 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004163 mConfig.keyRepeatTimeout * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004164}
4165
Michael Wright3dd60e22019-03-27 22:06:44 +00004166void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4167 const size_t numMonitors = monitors.size();
4168 for (size_t i = 0; i < numMonitors; i++) {
4169 const Monitor& monitor = monitors[i];
4170 const sp<InputChannel>& channel = monitor.inputChannel;
4171 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4172 dump += "\n";
4173 }
4174}
4175
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004176status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004177#if DEBUG_REGISTRATION
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004178 ALOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004179#endif
4180
4181 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004182 std::scoped_lock _l(mLock);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004183 sp<Connection> existingConnection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004184 if (existingConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004185 ALOGW("Attempted to register already registered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004186 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004187 return BAD_VALUE;
4188 }
4189
Michael Wright3dd60e22019-03-27 22:06:44 +00004190 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004191
4192 int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004193 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004194 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004195
Michael Wrightd02c5b62014-02-10 15:10:22 -08004196 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4197 } // release lock
4198
4199 // Wake the looper because some connections have changed.
4200 mLooper->wake();
4201 return OK;
4202}
4203
Michael Wright3dd60e22019-03-27 22:06:44 +00004204status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004205 int32_t displayId, bool isGestureMonitor) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004206 { // acquire lock
4207 std::scoped_lock _l(mLock);
4208
4209 if (displayId < 0) {
4210 ALOGW("Attempted to register input monitor without a specified display.");
4211 return BAD_VALUE;
4212 }
4213
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004214 if (inputChannel->getConnectionToken() == nullptr) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004215 ALOGW("Attempted to register input monitor without an identifying token.");
4216 return BAD_VALUE;
4217 }
4218
4219 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
4220
4221 const int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004222 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004223 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004224
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004225 auto& monitorsByDisplay =
4226 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Michael Wright3dd60e22019-03-27 22:06:44 +00004227 monitorsByDisplay[displayId].emplace_back(inputChannel);
4228
4229 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004230 }
4231 // Wake the looper because some connections have changed.
4232 mLooper->wake();
4233 return OK;
4234}
4235
Michael Wrightd02c5b62014-02-10 15:10:22 -08004236status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
4237#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004238 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004239#endif
4240
4241 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004242 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004243
4244 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
4245 if (status) {
4246 return status;
4247 }
4248 } // release lock
4249
4250 // Wake the poll loop because removing the connection may have changed the current
4251 // synchronization state.
4252 mLooper->wake();
4253 return OK;
4254}
4255
4256status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004257 bool notify) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004258 sp<Connection> connection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004259 if (connection == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004260 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004261 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004262 return BAD_VALUE;
4263 }
4264
John Recke0710582019-09-26 13:46:12 -07004265 [[maybe_unused]] const bool removed = removeByValue(mConnectionsByFd, connection);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004266 ALOG_ASSERT(removed);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004267 mInputChannelsByToken.erase(inputChannel->getConnectionToken());
Robert Carr5c8a0262018-10-03 16:30:44 -07004268
Michael Wrightd02c5b62014-02-10 15:10:22 -08004269 if (connection->monitor) {
4270 removeMonitorChannelLocked(inputChannel);
4271 }
4272
4273 mLooper->removeFd(inputChannel->getFd());
4274
4275 nsecs_t currentTime = now();
4276 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4277
4278 connection->status = Connection::STATUS_ZOMBIE;
4279 return OK;
4280}
4281
4282void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004283 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4284 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4285}
4286
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004287void InputDispatcher::removeMonitorChannelLocked(
4288 const sp<InputChannel>& inputChannel,
Michael Wright3dd60e22019-03-27 22:06:44 +00004289 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004290 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004291 std::vector<Monitor>& monitors = it->second;
4292 const size_t numMonitors = monitors.size();
4293 for (size_t i = 0; i < numMonitors; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004294 if (monitors[i].inputChannel == inputChannel) {
4295 monitors.erase(monitors.begin() + i);
4296 break;
4297 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004298 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004299 if (monitors.empty()) {
4300 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004301 } else {
4302 ++it;
4303 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004304 }
4305}
4306
Michael Wright3dd60e22019-03-27 22:06:44 +00004307status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4308 { // acquire lock
4309 std::scoped_lock _l(mLock);
4310 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4311
4312 if (!foundDisplayId) {
4313 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4314 return BAD_VALUE;
4315 }
4316 int32_t displayId = foundDisplayId.value();
4317
4318 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4319 if (stateIndex < 0) {
4320 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4321 return BAD_VALUE;
4322 }
4323
4324 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4325 std::optional<int32_t> foundDeviceId;
4326 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004327 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004328 foundDeviceId = state.deviceId;
4329 }
4330 }
4331 if (!foundDeviceId || !state.down) {
4332 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004333 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004334 return BAD_VALUE;
4335 }
4336 int32_t deviceId = foundDeviceId.value();
4337
4338 // Send cancel events to all the input channels we're stealing from.
4339 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004340 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004341 options.deviceId = deviceId;
4342 options.displayId = displayId;
4343 for (const TouchedWindow& window : state.windows) {
4344 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004345 if (channel != nullptr) {
4346 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4347 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004348 }
4349 // Then clear the current touch state so we stop dispatching to them as well.
4350 state.filterNonMonitors();
4351 }
4352 return OK;
4353}
4354
Michael Wright3dd60e22019-03-27 22:06:44 +00004355std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4356 const sp<IBinder>& token) {
4357 for (const auto& it : mGestureMonitorsByDisplay) {
4358 const std::vector<Monitor>& monitors = it.second;
4359 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004360 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004361 return it.first;
4362 }
4363 }
4364 }
4365 return std::nullopt;
4366}
4367
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004368sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) {
4369 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004370 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004371 }
4372
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004373 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004374 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004375 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004376 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004377 }
4378 }
Robert Carr4e670e52018-08-15 13:26:12 -07004379
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004380 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004381}
4382
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004383void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4384 const sp<Connection>& connection, uint32_t seq,
4385 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004386 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4387 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004388 commandEntry->connection = connection;
4389 commandEntry->eventTime = currentTime;
4390 commandEntry->seq = seq;
4391 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004392 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004393}
4394
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004395void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4396 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004397 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004398 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004399
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004400 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4401 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004402 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004403 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004404}
4405
chaviw0c06c6e2019-01-09 13:27:07 -08004406void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004407 const sp<InputWindowHandle>& newFocus) {
chaviw0c06c6e2019-01-09 13:27:07 -08004408 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4409 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004410 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4411 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004412 commandEntry->oldToken = oldToken;
4413 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004414 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004415}
4416
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004417void InputDispatcher::onANRLocked(nsecs_t currentTime,
4418 const sp<InputApplicationHandle>& applicationHandle,
4419 const sp<InputWindowHandle>& windowHandle, nsecs_t eventTime,
4420 nsecs_t waitStartTime, const char* reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004421 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4422 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4423 ALOGI("Application is not responding: %s. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004424 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
4425 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), dispatchLatency,
4426 waitDuration, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004427
4428 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004429 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004430 struct tm tm;
4431 localtime_r(&t, &tm);
4432 char timestr[64];
4433 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4434 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004435 mLastANRState += INDENT "ANR:\n";
4436 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004437 mLastANRState +=
4438 StringPrintf(INDENT2 "Window: %s\n",
4439 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004440 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4441 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4442 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004443 dumpDispatchStateLocked(mLastANRState);
4444
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004445 std::unique_ptr<CommandEntry> commandEntry =
4446 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004447 commandEntry->inputApplicationHandle = applicationHandle;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004448 commandEntry->inputChannel =
4449 windowHandle != nullptr ? getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004450 commandEntry->reason = reason;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004451 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004452}
4453
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004454void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004455 mLock.unlock();
4456
4457 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4458
4459 mLock.lock();
4460}
4461
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004462void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004463 sp<Connection> connection = commandEntry->connection;
4464
4465 if (connection->status != Connection::STATUS_ZOMBIE) {
4466 mLock.unlock();
4467
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004468 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004469
4470 mLock.lock();
4471 }
4472}
4473
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004474void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004475 sp<IBinder> oldToken = commandEntry->oldToken;
4476 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004477 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004478 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004479 mLock.lock();
4480}
4481
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004482void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004483 sp<IBinder> token =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004484 commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004485 mLock.unlock();
4486
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004487 nsecs_t newTimeout =
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004488 mPolicy->notifyANR(commandEntry->inputApplicationHandle, token, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004489
4490 mLock.lock();
4491
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004492 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004493}
4494
4495void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4496 CommandEntry* commandEntry) {
4497 KeyEntry* entry = commandEntry->keyEntry;
4498
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004499 KeyEvent event = createKeyEvent(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004500
4501 mLock.unlock();
4502
Michael Wright2b3c3302018-03-02 17:19:13 +00004503 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004504 sp<IBinder> token = commandEntry->inputChannel != nullptr
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004505 ? commandEntry->inputChannel->getConnectionToken()
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004506 : nullptr;
4507 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004508 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4509 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004510 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004511 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004512
4513 mLock.lock();
4514
4515 if (delay < 0) {
4516 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4517 } else if (!delay) {
4518 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4519 } else {
4520 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4521 entry->interceptKeyWakeupTime = now() + delay;
4522 }
4523 entry->release();
4524}
4525
chaviwfd6d3512019-03-25 13:23:49 -07004526void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4527 mLock.unlock();
4528 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4529 mLock.lock();
4530}
4531
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004532void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004533 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004534 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004535 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004536 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004537
4538 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07004539 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004540 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004541 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004542 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004543 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004544
4545 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4546 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4547 std::string msg =
4548 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4549 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4550 dispatchEntry->eventEntry->appendDescription(msg);
4551 ALOGI("%s", msg.c_str());
4552 }
4553
4554 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004555 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004556 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4557 restartEvent =
4558 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004559 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004560 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4561 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4562 handled);
4563 } else {
4564 restartEvent = false;
4565 }
4566
4567 // Dequeue the event and start the next cycle.
4568 // Note that because the lock might have been released, it is possible that the
4569 // contents of the wait queue to have been drained, so we need to double-check
4570 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004571 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4572 if (dispatchEntryIt != connection->waitQueue.end()) {
4573 dispatchEntry = *dispatchEntryIt;
4574 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004575 traceWaitQueueLength(connection);
4576 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004577 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004578 traceOutboundQueueLength(connection);
4579 } else {
4580 releaseDispatchEntry(dispatchEntry);
4581 }
4582 }
4583
4584 // Start the next dispatch cycle for this connection.
4585 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004586}
4587
4588bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004589 DispatchEntry* dispatchEntry,
4590 KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004591 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004592 if (!handled) {
4593 // Report the key as unhandled, since the fallback was not handled.
4594 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4595 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004596 return false;
4597 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004598
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004599 // Get the fallback key state.
4600 // Clear it out after dispatching the UP.
4601 int32_t originalKeyCode = keyEntry->keyCode;
4602 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4603 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4604 connection->inputState.removeFallbackKey(originalKeyCode);
4605 }
4606
4607 if (handled || !dispatchEntry->hasForegroundTarget()) {
4608 // If the application handles the original key for which we previously
4609 // generated a fallback or if the window is not a foreground window,
4610 // then cancel the associated fallback key, if any.
4611 if (fallbackKeyCode != -1) {
4612 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004613#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004614 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004615 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4616 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4617 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004618#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004619 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004620 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004621
4622 mLock.unlock();
4623
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004624 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004625 keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004626
4627 mLock.lock();
4628
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004629 // Cancel the fallback key.
4630 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004631 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004632 "application handled the original non-fallback key "
4633 "or is no longer a foreground target, "
4634 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004635 options.keyCode = fallbackKeyCode;
4636 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004637 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004638 connection->inputState.removeFallbackKey(originalKeyCode);
4639 }
4640 } else {
4641 // If the application did not handle a non-fallback key, first check
4642 // that we are in a good state to perform unhandled key event processing
4643 // Then ask the policy what to do with it.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004644 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN && keyEntry->repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004645 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004646#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004647 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004648 "since this is not an initial down. "
4649 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4650 originalKeyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004651#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004652 return false;
4653 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004654
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004655 // Dispatch the unhandled key to the policy.
4656#if DEBUG_OUTBOUND_EVENT_DETAILS
4657 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004658 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4659 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004660#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004661 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004662
4663 mLock.unlock();
4664
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004665 bool fallback =
4666 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
4667 &event, keyEntry->policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004668
4669 mLock.lock();
4670
4671 if (connection->status != Connection::STATUS_NORMAL) {
4672 connection->inputState.removeFallbackKey(originalKeyCode);
4673 return false;
4674 }
4675
4676 // Latch the fallback keycode for this key on an initial down.
4677 // The fallback keycode cannot change at any other point in the lifecycle.
4678 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004679 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004680 fallbackKeyCode = event.getKeyCode();
4681 } else {
4682 fallbackKeyCode = AKEYCODE_UNKNOWN;
4683 }
4684 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4685 }
4686
4687 ALOG_ASSERT(fallbackKeyCode != -1);
4688
4689 // Cancel the fallback key if the policy decides not to send it anymore.
4690 // We will continue to dispatch the key to the policy but we will no
4691 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004692 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
4693 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004694#if DEBUG_OUTBOUND_EVENT_DETAILS
4695 if (fallback) {
4696 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004697 "as a fallback for %d, but on the DOWN it had requested "
4698 "to send %d instead. Fallback canceled.",
4699 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004700 } else {
4701 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004702 "but on the DOWN it had requested to send %d. "
4703 "Fallback canceled.",
4704 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004705 }
4706#endif
4707
4708 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4709 "canceling fallback, policy no longer desires it");
4710 options.keyCode = fallbackKeyCode;
4711 synthesizeCancelationEventsForConnectionLocked(connection, options);
4712
4713 fallback = false;
4714 fallbackKeyCode = AKEYCODE_UNKNOWN;
4715 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004716 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004717 }
4718 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004719
4720#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004721 {
4722 std::string msg;
4723 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4724 connection->inputState.getFallbackKeys();
4725 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004726 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004727 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004728 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004729 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004730 }
4731#endif
4732
4733 if (fallback) {
4734 // Restart the dispatch cycle using the fallback key.
4735 keyEntry->eventTime = event.getEventTime();
4736 keyEntry->deviceId = event.getDeviceId();
4737 keyEntry->source = event.getSource();
4738 keyEntry->displayId = event.getDisplayId();
4739 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4740 keyEntry->keyCode = fallbackKeyCode;
4741 keyEntry->scanCode = event.getScanCode();
4742 keyEntry->metaState = event.getMetaState();
4743 keyEntry->repeatCount = event.getRepeatCount();
4744 keyEntry->downTime = event.getDownTime();
4745 keyEntry->syntheticRepeat = false;
4746
4747#if DEBUG_OUTBOUND_EVENT_DETAILS
4748 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004749 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4750 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004751#endif
4752 return true; // restart the event
4753 } else {
4754#if DEBUG_OUTBOUND_EVENT_DETAILS
4755 ALOGD("Unhandled key event: No fallback key.");
4756#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004757
4758 // Report the key as unhandled, since there is no fallback key.
4759 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004760 }
4761 }
4762 return false;
4763}
4764
4765bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004766 DispatchEntry* dispatchEntry,
4767 MotionEntry* motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004768 return false;
4769}
4770
4771void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4772 mLock.unlock();
4773
4774 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4775
4776 mLock.lock();
4777}
4778
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004779KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
4780 KeyEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06004781 event.initialize(entry.deviceId, entry.source, entry.displayId, INVALID_HMAC, entry.action,
4782 entry.flags, entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount,
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004783 entry.downTime, entry.eventTime);
4784 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004785}
4786
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004787void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004788 int32_t injectionResult,
4789 nsecs_t timeSpentWaitingForApplication) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004790 // TODO Write some statistics about how long we spend waiting.
4791}
4792
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05004793/**
4794 * Report the touch event latency to the statsd server.
4795 * Input events are reported for statistics if:
4796 * - This is a touchscreen event
4797 * - InputFilter is not enabled
4798 * - Event is not injected or synthesized
4799 *
4800 * Statistics should be reported before calling addValue, to prevent a fresh new sample
4801 * from getting aggregated with the "old" data.
4802 */
4803void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
4804 REQUIRES(mLock) {
4805 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
4806 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
4807 if (!reportForStatistics) {
4808 return;
4809 }
4810
4811 if (mTouchStatistics.shouldReport()) {
4812 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
4813 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
4814 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
4815 mTouchStatistics.reset();
4816 }
4817 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
4818 mTouchStatistics.addValue(latencyMicros);
4819}
4820
Michael Wrightd02c5b62014-02-10 15:10:22 -08004821void InputDispatcher::traceInboundQueueLengthLocked() {
4822 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004823 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004824 }
4825}
4826
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004827void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004828 if (ATRACE_ENABLED()) {
4829 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004830 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004831 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004832 }
4833}
4834
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004835void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004836 if (ATRACE_ENABLED()) {
4837 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004838 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004839 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004840 }
4841}
4842
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004843void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004844 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004845
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004846 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004847 dumpDispatchStateLocked(dump);
4848
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004849 if (!mLastANRState.empty()) {
4850 dump += "\nInput Dispatcher State at time of last ANR:\n";
4851 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004852 }
4853}
4854
4855void InputDispatcher::monitor() {
4856 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004857 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004858 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004859 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004860}
4861
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08004862/**
4863 * Wake up the dispatcher and wait until it processes all events and commands.
4864 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
4865 * this method can be safely called from any thread, as long as you've ensured that
4866 * the work you are interested in completing has already been queued.
4867 */
4868bool InputDispatcher::waitForIdle() {
4869 /**
4870 * Timeout should represent the longest possible time that a device might spend processing
4871 * events and commands.
4872 */
4873 constexpr std::chrono::duration TIMEOUT = 100ms;
4874 std::unique_lock lock(mLock);
4875 mLooper->wake();
4876 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
4877 return result == std::cv_status::no_timeout;
4878}
4879
Garfield Tane84e6f92019-08-29 17:28:41 -07004880} // namespace android::inputdispatcher