blob: 70cee18330db03b0fc594cb2c0edef216a9ccd2a [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);
Gang Wange9087892020-01-07 12:17:14 -05002436 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(*keyEntry);
2437 verifiedEvent.flags = dispatchEntry->resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
2438 verifiedEvent.action = dispatchEntry->resolvedAction;
2439 std::array<uint8_t, 32> hmac = mHmacKeyManager.sign(verifiedEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002440
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002441 // Publish the key event.
2442 status = connection->inputPublisher
2443 .publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId,
2444 keyEntry->source, keyEntry->displayId,
Gang Wange9087892020-01-07 12:17:14 -05002445 std::move(hmac), dispatchEntry->resolvedAction,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002446 dispatchEntry->resolvedFlags, keyEntry->keyCode,
2447 keyEntry->scanCode, keyEntry->metaState,
2448 keyEntry->repeatCount, keyEntry->downTime,
2449 keyEntry->eventTime);
2450 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002451 }
2452
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002453 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002454 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002455
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002456 PointerCoords scaledCoords[MAX_POINTERS];
2457 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2458
chaviw82357092020-01-28 13:13:06 -08002459 // Set the X and Y offset and X and Y scale depending on the input source.
2460 float xOffset = 0.0f, yOffset = 0.0f;
2461 float xScale = 1.0f, yScale = 1.0f;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002462 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
2463 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2464 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002465 xScale = dispatchEntry->windowXScale;
2466 yScale = dispatchEntry->windowYScale;
2467 xOffset = dispatchEntry->xOffset * xScale;
2468 yOffset = dispatchEntry->yOffset * yScale;
2469 if (globalScaleFactor != 1.0f) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002470 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2471 scaledCoords[i] = motionEntry->pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002472 // Don't apply window scale here since we don't want scale to affect raw
2473 // coordinates. The scale will be sent back to the client and applied
2474 // later when requesting relative coordinates.
2475 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2476 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002477 }
2478 usingCoords = scaledCoords;
2479 }
2480 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002481 // We don't want the dispatch target to know.
2482 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
2483 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2484 scaledCoords[i].clear();
2485 }
2486 usingCoords = scaledCoords;
2487 }
2488 }
Gang Wange9087892020-01-07 12:17:14 -05002489 VerifiedMotionEvent verifiedEvent =
2490 verifiedMotionEventFromMotionEntry(*motionEntry);
2491 verifiedEvent.actionMasked =
2492 dispatchEntry->resolvedAction & AMOTION_EVENT_ACTION_MASK;
2493 verifiedEvent.flags = dispatchEntry->resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
2494 std::array<uint8_t, 32> hmac = mHmacKeyManager.sign(verifiedEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002495
2496 // Publish the motion event.
2497 status = connection->inputPublisher
2498 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2499 motionEntry->source, motionEntry->displayId,
Gang Wange9087892020-01-07 12:17:14 -05002500 std::move(hmac), dispatchEntry->resolvedAction,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002501 motionEntry->actionButton,
2502 dispatchEntry->resolvedFlags,
2503 motionEntry->edgeFlags, motionEntry->metaState,
2504 motionEntry->buttonState,
chaviw82357092020-01-28 13:13:06 -08002505 motionEntry->classification, xScale, yScale,
2506 xOffset, yOffset, motionEntry->xPrecision,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002507 motionEntry->yPrecision,
2508 motionEntry->xCursorPosition,
2509 motionEntry->yCursorPosition,
2510 motionEntry->downTime, motionEntry->eventTime,
2511 motionEntry->pointerCount,
2512 motionEntry->pointerProperties, usingCoords);
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05002513 reportTouchEventForStatistics(*motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002514 break;
2515 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002516 case EventEntry::Type::FOCUS: {
2517 FocusEntry* focusEntry = static_cast<FocusEntry*>(eventEntry);
2518 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
2519 focusEntry->hasFocus,
2520 mInTouchMode);
2521 break;
2522 }
2523
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002524 case EventEntry::Type::CONFIGURATION_CHANGED:
2525 case EventEntry::Type::DEVICE_RESET: {
2526 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
2527 EventEntry::typeToString(eventEntry->type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002528 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002529 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002530 }
2531
2532 // Check the result.
2533 if (status) {
2534 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002535 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002536 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002537 "This is unexpected because the wait queue is empty, so the pipe "
2538 "should be empty and we shouldn't have any problems writing an "
2539 "event to it, status=%d",
2540 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002541 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2542 } else {
2543 // Pipe is full and we are waiting for the app to finish process some events
2544 // before sending more events to it.
2545#if DEBUG_DISPATCH_CYCLE
2546 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002547 "waiting for the application to catch up",
2548 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002549#endif
2550 connection->inputPublisherBlocked = true;
2551 }
2552 } else {
2553 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002554 "status=%d",
2555 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002556 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2557 }
2558 return;
2559 }
2560
2561 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002562 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2563 connection->outboundQueue.end(),
2564 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002565 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002566 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002567 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002568 }
2569}
2570
2571void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002572 const sp<Connection>& connection, uint32_t seq,
2573 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002574#if DEBUG_DISPATCH_CYCLE
2575 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002576 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002577#endif
2578
2579 connection->inputPublisherBlocked = false;
2580
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002581 if (connection->status == Connection::STATUS_BROKEN ||
2582 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002583 return;
2584 }
2585
2586 // Notify other system components and prepare to start the next dispatch cycle.
2587 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2588}
2589
2590void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002591 const sp<Connection>& connection,
2592 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002593#if DEBUG_DISPATCH_CYCLE
2594 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002595 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002596#endif
2597
2598 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002599 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002600 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002601 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002602 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002603
2604 // The connection appears to be unrecoverably broken.
2605 // Ignore already broken or zombie connections.
2606 if (connection->status == Connection::STATUS_NORMAL) {
2607 connection->status = Connection::STATUS_BROKEN;
2608
2609 if (notify) {
2610 // Notify other system components.
2611 onDispatchCycleBrokenLocked(currentTime, connection);
2612 }
2613 }
2614}
2615
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002616void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2617 while (!queue.empty()) {
2618 DispatchEntry* dispatchEntry = queue.front();
2619 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002620 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002621 }
2622}
2623
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002624void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002625 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002626 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002627 }
2628 delete dispatchEntry;
2629}
2630
2631int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2632 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2633
2634 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002635 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002636
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002637 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002638 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002639 "fd=%d, events=0x%x",
2640 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002641 return 0; // remove the callback
2642 }
2643
2644 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002645 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002646 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2647 if (!(events & ALOOPER_EVENT_INPUT)) {
2648 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002649 "events=0x%x",
2650 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002651 return 1;
2652 }
2653
2654 nsecs_t currentTime = now();
2655 bool gotOne = false;
2656 status_t status;
2657 for (;;) {
2658 uint32_t seq;
2659 bool handled;
2660 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2661 if (status) {
2662 break;
2663 }
2664 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2665 gotOne = true;
2666 }
2667 if (gotOne) {
2668 d->runCommandsLockedInterruptible();
2669 if (status == WOULD_BLOCK) {
2670 return 1;
2671 }
2672 }
2673
2674 notify = status != DEAD_OBJECT || !connection->monitor;
2675 if (notify) {
2676 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002677 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002678 }
2679 } else {
2680 // Monitor channels are never explicitly unregistered.
2681 // We do it automatically when the remote endpoint is closed so don't warn
2682 // about them.
2683 notify = !connection->monitor;
2684 if (notify) {
2685 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002686 "events=0x%x",
2687 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002688 }
2689 }
2690
2691 // Unregister the channel.
2692 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2693 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002694 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08002695}
2696
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002697void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002698 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002699 for (const auto& pair : mConnectionsByFd) {
2700 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002701 }
2702}
2703
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002704void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002705 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002706 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2707 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2708}
2709
2710void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2711 const CancelationOptions& options,
2712 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2713 for (const auto& it : monitorsByDisplay) {
2714 const std::vector<Monitor>& monitors = it.second;
2715 for (const Monitor& monitor : monitors) {
2716 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002717 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002718 }
2719}
2720
Michael Wrightd02c5b62014-02-10 15:10:22 -08002721void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2722 const sp<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002723 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002724 if (connection == nullptr) {
2725 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002726 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002727
2728 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002729}
2730
2731void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2732 const sp<Connection>& connection, const CancelationOptions& options) {
2733 if (connection->status == Connection::STATUS_BROKEN) {
2734 return;
2735 }
2736
2737 nsecs_t currentTime = now();
2738
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07002739 std::vector<EventEntry*> cancelationEvents =
2740 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002741
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002742 if (cancelationEvents.empty()) {
2743 return;
2744 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002745#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002746 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
2747 "with reality: %s, mode=%d.",
2748 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
2749 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002750#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08002751
2752 InputTarget target;
2753 sp<InputWindowHandle> windowHandle =
2754 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
2755 if (windowHandle != nullptr) {
2756 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2757 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2758 windowInfo->windowXScale, windowInfo->windowYScale);
2759 target.globalScaleFactor = windowInfo->globalScaleFactor;
2760 }
2761 target.inputChannel = connection->inputChannel;
2762 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2763
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002764 for (size_t i = 0; i < cancelationEvents.size(); i++) {
2765 EventEntry* cancelationEventEntry = cancelationEvents[i];
2766 switch (cancelationEventEntry->type) {
2767 case EventEntry::Type::KEY: {
2768 logOutboundKeyDetails("cancel - ",
2769 static_cast<const KeyEntry&>(*cancelationEventEntry));
2770 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002771 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002772 case EventEntry::Type::MOTION: {
2773 logOutboundMotionDetails("cancel - ",
2774 static_cast<const MotionEntry&>(*cancelationEventEntry));
2775 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002776 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002777 case EventEntry::Type::FOCUS: {
2778 LOG_ALWAYS_FATAL("Canceling focus events is not supported");
2779 break;
2780 }
2781 case EventEntry::Type::CONFIGURATION_CHANGED:
2782 case EventEntry::Type::DEVICE_RESET: {
2783 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2784 EventEntry::typeToString(cancelationEventEntry->type));
2785 break;
2786 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002787 }
2788
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002789 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
2790 target, InputTarget::FLAG_DISPATCH_AS_IS);
2791
2792 cancelationEventEntry->release();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002793 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002794
2795 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002796}
2797
Svet Ganov5d3bc372020-01-26 23:11:07 -08002798void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
2799 const sp<Connection>& connection) {
2800 if (connection->status == Connection::STATUS_BROKEN) {
2801 return;
2802 }
2803
2804 nsecs_t currentTime = now();
2805
2806 std::vector<EventEntry*> downEvents =
2807 connection->inputState.synthesizePointerDownEvents(currentTime);
2808
2809 if (downEvents.empty()) {
2810 return;
2811 }
2812
2813#if DEBUG_OUTBOUND_EVENT_DETAILS
2814 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
2815 connection->getInputChannelName().c_str(), downEvents.size());
2816#endif
2817
2818 InputTarget target;
2819 sp<InputWindowHandle> windowHandle =
2820 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
2821 if (windowHandle != nullptr) {
2822 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2823 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2824 windowInfo->windowXScale, windowInfo->windowYScale);
2825 target.globalScaleFactor = windowInfo->globalScaleFactor;
2826 }
2827 target.inputChannel = connection->inputChannel;
2828 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2829
2830 for (EventEntry* downEventEntry : downEvents) {
2831 switch (downEventEntry->type) {
2832 case EventEntry::Type::MOTION: {
2833 logOutboundMotionDetails("down - ",
2834 static_cast<const MotionEntry&>(*downEventEntry));
2835 break;
2836 }
2837
2838 case EventEntry::Type::KEY:
2839 case EventEntry::Type::FOCUS:
2840 case EventEntry::Type::CONFIGURATION_CHANGED:
2841 case EventEntry::Type::DEVICE_RESET: {
2842 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2843 EventEntry::typeToString(downEventEntry->type));
2844 break;
2845 }
2846 }
2847
2848 enqueueDispatchEntryLocked(connection, downEventEntry, // increments ref
2849 target, InputTarget::FLAG_DISPATCH_AS_IS);
2850
2851 downEventEntry->release();
2852 }
2853
2854 startDispatchCycleLocked(currentTime, connection);
2855}
2856
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002857MotionEntry* InputDispatcher::splitMotionEvent(const MotionEntry& originalMotionEntry,
Garfield Tane84e6f92019-08-29 17:28:41 -07002858 BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002859 ALOG_ASSERT(pointerIds.value != 0);
2860
2861 uint32_t splitPointerIndexMap[MAX_POINTERS];
2862 PointerProperties splitPointerProperties[MAX_POINTERS];
2863 PointerCoords splitPointerCoords[MAX_POINTERS];
2864
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002865 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002866 uint32_t splitPointerCount = 0;
2867
2868 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002869 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002870 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002871 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002872 uint32_t pointerId = uint32_t(pointerProperties.id);
2873 if (pointerIds.hasBit(pointerId)) {
2874 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2875 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2876 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002877 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002878 splitPointerCount += 1;
2879 }
2880 }
2881
2882 if (splitPointerCount != pointerIds.count()) {
2883 // This is bad. We are missing some of the pointers that we expected to deliver.
2884 // Most likely this indicates that we received an ACTION_MOVE events that has
2885 // different pointer ids than we expected based on the previous ACTION_DOWN
2886 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2887 // in this way.
2888 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002889 "we expected there to be %d pointers. This probably means we received "
2890 "a broken sequence of pointer ids from the input device.",
2891 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002892 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002893 }
2894
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002895 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002896 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002897 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
2898 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002899 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2900 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002901 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002902 uint32_t pointerId = uint32_t(pointerProperties.id);
2903 if (pointerIds.hasBit(pointerId)) {
2904 if (pointerIds.count() == 1) {
2905 // The first/last pointer went down/up.
2906 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002907 ? AMOTION_EVENT_ACTION_DOWN
2908 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002909 } else {
2910 // A secondary pointer went down/up.
2911 uint32_t splitPointerIndex = 0;
2912 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2913 splitPointerIndex += 1;
2914 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002915 action = maskedAction |
2916 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002917 }
2918 } else {
2919 // An unrelated pointer changed.
2920 action = AMOTION_EVENT_ACTION_MOVE;
2921 }
2922 }
2923
Garfield Tan00f511d2019-06-12 16:55:40 -07002924 MotionEntry* splitMotionEntry =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002925 new MotionEntry(originalMotionEntry.sequenceNum, originalMotionEntry.eventTime,
2926 originalMotionEntry.deviceId, originalMotionEntry.source,
2927 originalMotionEntry.displayId, originalMotionEntry.policyFlags, action,
2928 originalMotionEntry.actionButton, originalMotionEntry.flags,
2929 originalMotionEntry.metaState, originalMotionEntry.buttonState,
2930 originalMotionEntry.classification, originalMotionEntry.edgeFlags,
2931 originalMotionEntry.xPrecision, originalMotionEntry.yPrecision,
2932 originalMotionEntry.xCursorPosition,
2933 originalMotionEntry.yCursorPosition, originalMotionEntry.downTime,
Garfield Tan00f511d2019-06-12 16:55:40 -07002934 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002935
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002936 if (originalMotionEntry.injectionState) {
2937 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002938 splitMotionEntry->injectionState->refCount += 1;
2939 }
2940
2941 return splitMotionEntry;
2942}
2943
2944void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2945#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002946 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002947#endif
2948
2949 bool needWake;
2950 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002951 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002952
Prabir Pradhan42611e02018-11-27 14:04:02 -08002953 ConfigurationChangedEntry* newEntry =
2954 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002955 needWake = enqueueInboundEventLocked(newEntry);
2956 } // release lock
2957
2958 if (needWake) {
2959 mLooper->wake();
2960 }
2961}
2962
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002963/**
2964 * If one of the meta shortcuts is detected, process them here:
2965 * Meta + Backspace -> generate BACK
2966 * Meta + Enter -> generate HOME
2967 * This will potentially overwrite keyCode and metaState.
2968 */
2969void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002970 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002971 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2972 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2973 if (keyCode == AKEYCODE_DEL) {
2974 newKeyCode = AKEYCODE_BACK;
2975 } else if (keyCode == AKEYCODE_ENTER) {
2976 newKeyCode = AKEYCODE_HOME;
2977 }
2978 if (newKeyCode != AKEYCODE_UNKNOWN) {
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 mReplacedKeys.add(replacement, newKeyCode);
2982 keyCode = newKeyCode;
2983 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2984 }
2985 } else if (action == AKEY_EVENT_ACTION_UP) {
2986 // In order to maintain a consistent stream of up and down events, check to see if the key
2987 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2988 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002989 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002990 struct KeyReplacement replacement = {keyCode, deviceId};
2991 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2992 if (index >= 0) {
2993 keyCode = mReplacedKeys.valueAt(index);
2994 mReplacedKeys.removeItemsAt(index);
2995 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2996 }
2997 }
2998}
2999
Michael Wrightd02c5b62014-02-10 15:10:22 -08003000void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3001#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003002 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3003 "policyFlags=0x%x, action=0x%x, "
3004 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3005 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3006 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3007 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003008#endif
3009 if (!validateKeyEvent(args->action)) {
3010 return;
3011 }
3012
3013 uint32_t policyFlags = args->policyFlags;
3014 int32_t flags = args->flags;
3015 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003016 // InputDispatcher tracks and generates key repeats on behalf of
3017 // whatever notifies it, so repeatCount should always be set to 0
3018 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003019 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3020 policyFlags |= POLICY_FLAG_VIRTUAL;
3021 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3022 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003023 if (policyFlags & POLICY_FLAG_FUNCTION) {
3024 metaState |= AMETA_FUNCTION_ON;
3025 }
3026
3027 policyFlags |= POLICY_FLAG_TRUSTED;
3028
Michael Wright78f24442014-08-06 15:55:28 -07003029 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003030 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003031
Michael Wrightd02c5b62014-02-10 15:10:22 -08003032 KeyEvent event;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003033 event.initialize(args->sequenceNum, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3034 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3035 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003036
Michael Wright2b3c3302018-03-02 17:19:13 +00003037 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003038 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003039 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3040 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003041 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003042 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003043
Michael Wrightd02c5b62014-02-10 15:10:22 -08003044 bool needWake;
3045 { // acquire lock
3046 mLock.lock();
3047
3048 if (shouldSendKeyToInputFilterLocked(args)) {
3049 mLock.unlock();
3050
3051 policyFlags |= POLICY_FLAG_FILTERED;
3052 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3053 return; // event was consumed by the filter
3054 }
3055
3056 mLock.lock();
3057 }
3058
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003059 KeyEntry* newEntry =
3060 new KeyEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
3061 args->displayId, policyFlags, args->action, flags, keyCode,
3062 args->scanCode, metaState, repeatCount, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003063
3064 needWake = enqueueInboundEventLocked(newEntry);
3065 mLock.unlock();
3066 } // release lock
3067
3068 if (needWake) {
3069 mLooper->wake();
3070 }
3071}
3072
3073bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3074 return mInputFilterEnabled;
3075}
3076
3077void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3078#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08003079 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07003080 ", policyFlags=0x%x, "
3081 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3082 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003083 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07003084 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3085 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
Jaewan Kim372fbe42019-10-02 10:58:46 +09003086 args->edgeFlags, args->xPrecision, args->yPrecision, args->xCursorPosition,
Garfield Tan00f511d2019-06-12 16:55:40 -07003087 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003088 for (uint32_t i = 0; i < args->pointerCount; i++) {
3089 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003090 "x=%f, y=%f, pressure=%f, size=%f, "
3091 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3092 "orientation=%f",
3093 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3094 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3095 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3096 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3097 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3098 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3099 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3100 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3101 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3102 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003103 }
3104#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003105 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3106 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003107 return;
3108 }
3109
3110 uint32_t policyFlags = args->policyFlags;
3111 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003112
3113 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003114 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003115 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3116 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003117 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003118 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003119
3120 bool needWake;
3121 { // acquire lock
3122 mLock.lock();
3123
3124 if (shouldSendMotionToInputFilterLocked(args)) {
3125 mLock.unlock();
3126
3127 MotionEvent event;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003128 event.initialize(args->sequenceNum, args->deviceId, args->source, args->displayId,
3129 INVALID_HMAC, args->action, args->actionButton, args->flags,
3130 args->edgeFlags, args->metaState, args->buttonState,
3131 args->classification, 1 /*xScale*/, 1 /*yScale*/, 0 /* xOffset */,
3132 0 /* yOffset */, args->xPrecision, args->yPrecision,
3133 args->xCursorPosition, args->yCursorPosition, args->downTime,
3134 args->eventTime, args->pointerCount, args->pointerProperties,
3135 args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003136
3137 policyFlags |= POLICY_FLAG_FILTERED;
3138 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3139 return; // event was consumed by the filter
3140 }
3141
3142 mLock.lock();
3143 }
3144
3145 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07003146 MotionEntry* newEntry =
3147 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
3148 args->displayId, policyFlags, args->action, args->actionButton,
3149 args->flags, args->metaState, args->buttonState,
3150 args->classification, args->edgeFlags, args->xPrecision,
3151 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3152 args->downTime, args->pointerCount, args->pointerProperties,
3153 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003154
3155 needWake = enqueueInboundEventLocked(newEntry);
3156 mLock.unlock();
3157 } // release lock
3158
3159 if (needWake) {
3160 mLooper->wake();
3161 }
3162}
3163
3164bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003165 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003166}
3167
3168void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3169#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003170 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003171 "switchMask=0x%08x",
3172 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003173#endif
3174
3175 uint32_t policyFlags = args->policyFlags;
3176 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003177 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003178}
3179
3180void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3181#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003182 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3183 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003184#endif
3185
3186 bool needWake;
3187 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003188 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003189
Prabir Pradhan42611e02018-11-27 14:04:02 -08003190 DeviceResetEntry* newEntry =
3191 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003192 needWake = enqueueInboundEventLocked(newEntry);
3193 } // release lock
3194
3195 if (needWake) {
3196 mLooper->wake();
3197 }
3198}
3199
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003200int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid,
3201 int32_t injectorUid, int32_t syncMode,
3202 int32_t timeoutMillis, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003203#if DEBUG_INBOUND_EVENT_DETAILS
3204 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003205 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
3206 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003207#endif
3208
3209 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
3210
3211 policyFlags |= POLICY_FLAG_INJECTED;
3212 if (hasInjectionPermission(injectorPid, injectorUid)) {
3213 policyFlags |= POLICY_FLAG_TRUSTED;
3214 }
3215
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003216 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003217 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003218 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003219 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3220 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003221 if (!validateKeyEvent(action)) {
3222 return INPUT_EVENT_INJECTION_FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003223 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003224
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003225 int32_t flags = incomingKey.getFlags();
3226 int32_t keyCode = incomingKey.getKeyCode();
3227 int32_t metaState = incomingKey.getMetaState();
3228 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003229 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003230 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003231 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003232 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3233 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3234 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003235
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003236 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3237 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003238 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003239
3240 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3241 android::base::Timer t;
3242 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3243 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3244 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3245 std::to_string(t.duration().count()).c_str());
3246 }
3247 }
3248
3249 mLock.lock();
3250 KeyEntry* injectedEntry =
Garfield Tan4cc839f2020-01-24 11:26:14 -08003251 new KeyEntry(incomingKey.getId(), incomingKey.getEventTime(),
3252 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3253 incomingKey.getDisplayId(), policyFlags, action, flags,
3254 incomingKey.getKeyCode(), incomingKey.getScanCode(),
3255 incomingKey.getMetaState(), incomingKey.getRepeatCount(),
3256 incomingKey.getDownTime());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003257 injectedEntries.push(injectedEntry);
3258 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003259 }
3260
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003261 case AINPUT_EVENT_TYPE_MOTION: {
3262 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3263 int32_t action = motionEvent->getAction();
3264 size_t pointerCount = motionEvent->getPointerCount();
3265 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3266 int32_t actionButton = motionEvent->getActionButton();
3267 int32_t displayId = motionEvent->getDisplayId();
3268 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
3269 return INPUT_EVENT_INJECTION_FAILED;
3270 }
3271
3272 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3273 nsecs_t eventTime = motionEvent->getEventTime();
3274 android::base::Timer t;
3275 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3276 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3277 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3278 std::to_string(t.duration().count()).c_str());
3279 }
3280 }
3281
3282 mLock.lock();
3283 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3284 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
3285 MotionEntry* injectedEntry =
Garfield Tan4cc839f2020-01-24 11:26:14 -08003286 new MotionEntry(motionEvent->getId(), *sampleEventTimes, VIRTUAL_KEYBOARD_ID,
3287 motionEvent->getSource(), motionEvent->getDisplayId(),
3288 policyFlags, action, actionButton, motionEvent->getFlags(),
3289 motionEvent->getMetaState(), motionEvent->getButtonState(),
3290 motionEvent->getClassification(), motionEvent->getEdgeFlags(),
3291 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
Garfield Tan00f511d2019-06-12 16:55:40 -07003292 motionEvent->getRawXCursorPosition(),
3293 motionEvent->getRawYCursorPosition(),
3294 motionEvent->getDownTime(), uint32_t(pointerCount),
3295 pointerProperties, samplePointerCoords,
3296 motionEvent->getXOffset(), motionEvent->getYOffset());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003297 injectedEntries.push(injectedEntry);
3298 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3299 sampleEventTimes += 1;
3300 samplePointerCoords += pointerCount;
3301 MotionEntry* nextInjectedEntry =
Garfield Tan4cc839f2020-01-24 11:26:14 -08003302 new MotionEntry(motionEvent->getId(), *sampleEventTimes,
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003303 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003304 motionEvent->getDisplayId(), policyFlags, action,
3305 actionButton, motionEvent->getFlags(),
3306 motionEvent->getMetaState(), motionEvent->getButtonState(),
3307 motionEvent->getClassification(),
3308 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3309 motionEvent->getYPrecision(),
3310 motionEvent->getRawXCursorPosition(),
3311 motionEvent->getRawYCursorPosition(),
3312 motionEvent->getDownTime(), uint32_t(pointerCount),
3313 pointerProperties, samplePointerCoords,
3314 motionEvent->getXOffset(), motionEvent->getYOffset());
3315 injectedEntries.push(nextInjectedEntry);
3316 }
3317 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003319
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003320 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003321 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003322 return INPUT_EVENT_INJECTION_FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003323 }
3324
3325 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3326 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3327 injectionState->injectionIsAsync = true;
3328 }
3329
3330 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003331 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003332
3333 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003334 while (!injectedEntries.empty()) {
3335 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3336 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003337 }
3338
3339 mLock.unlock();
3340
3341 if (needWake) {
3342 mLooper->wake();
3343 }
3344
3345 int32_t injectionResult;
3346 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003347 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003348
3349 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3350 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3351 } else {
3352 for (;;) {
3353 injectionResult = injectionState->injectionResult;
3354 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3355 break;
3356 }
3357
3358 nsecs_t remainingTimeout = endTime - now();
3359 if (remainingTimeout <= 0) {
3360#if DEBUG_INJECTION
3361 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003362 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003363#endif
3364 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3365 break;
3366 }
3367
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003368 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003369 }
3370
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003371 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED &&
3372 syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003373 while (injectionState->pendingForegroundDispatches != 0) {
3374#if DEBUG_INJECTION
3375 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003376 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003377#endif
3378 nsecs_t remainingTimeout = endTime - now();
3379 if (remainingTimeout <= 0) {
3380#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003381 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3382 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003383#endif
3384 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3385 break;
3386 }
3387
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003388 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003389 }
3390 }
3391 }
3392
3393 injectionState->release();
3394 } // release lock
3395
3396#if DEBUG_INJECTION
3397 ALOGD("injectInputEvent - Finished with result %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003398 "injectorPid=%d, injectorUid=%d",
3399 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003400#endif
3401
3402 return injectionResult;
3403}
3404
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003405std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05003406 std::array<uint8_t, 32> calculatedHmac;
3407 std::unique_ptr<VerifiedInputEvent> result;
3408 switch (event.getType()) {
3409 case AINPUT_EVENT_TYPE_KEY: {
3410 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
3411 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
3412 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
3413 calculatedHmac = mHmacKeyManager.sign(verifiedKeyEvent);
3414 break;
3415 }
3416 case AINPUT_EVENT_TYPE_MOTION: {
3417 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
3418 VerifiedMotionEvent verifiedMotionEvent =
3419 verifiedMotionEventFromMotionEvent(motionEvent);
3420 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
3421 calculatedHmac = mHmacKeyManager.sign(verifiedMotionEvent);
3422 break;
3423 }
3424 default: {
3425 ALOGE("Cannot verify events of type %" PRId32, event.getType());
3426 return nullptr;
3427 }
3428 }
3429 if (calculatedHmac == INVALID_HMAC) {
3430 return nullptr;
3431 }
3432 if (calculatedHmac != event.getHmac()) {
3433 return nullptr;
3434 }
3435 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003436}
3437
Michael Wrightd02c5b62014-02-10 15:10:22 -08003438bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003439 return injectorUid == 0 ||
3440 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003441}
3442
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003443void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003444 InjectionState* injectionState = entry->injectionState;
3445 if (injectionState) {
3446#if DEBUG_INJECTION
3447 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003448 "injectorPid=%d, injectorUid=%d",
3449 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003450#endif
3451
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003452 if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003453 // Log the outcome since the injector did not wait for the injection result.
3454 switch (injectionResult) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003455 case INPUT_EVENT_INJECTION_SUCCEEDED:
3456 ALOGV("Asynchronous input event injection succeeded.");
3457 break;
3458 case INPUT_EVENT_INJECTION_FAILED:
3459 ALOGW("Asynchronous input event injection failed.");
3460 break;
3461 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3462 ALOGW("Asynchronous input event injection permission denied.");
3463 break;
3464 case INPUT_EVENT_INJECTION_TIMED_OUT:
3465 ALOGW("Asynchronous input event injection timed out.");
3466 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003467 }
3468 }
3469
3470 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003471 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003472 }
3473}
3474
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003475void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003476 InjectionState* injectionState = entry->injectionState;
3477 if (injectionState) {
3478 injectionState->pendingForegroundDispatches += 1;
3479 }
3480}
3481
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003482void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003483 InjectionState* injectionState = entry->injectionState;
3484 if (injectionState) {
3485 injectionState->pendingForegroundDispatches -= 1;
3486
3487 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003488 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003489 }
3490 }
3491}
3492
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003493std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3494 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003495 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003496}
3497
Michael Wrightd02c5b62014-02-10 15:10:22 -08003498sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003499 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003500 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003501 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3502 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003503 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003504 return windowHandle;
3505 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003506 }
3507 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003508 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003509}
3510
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003511bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003512 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003513 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3514 for (const sp<InputWindowHandle>& handle : windowHandles) {
3515 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003516 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003517 ALOGE("Found window %s in display %" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003518 ", but it should belong to display %" PRId32,
3519 windowHandle->getName().c_str(), it.first,
3520 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003521 }
3522 return true;
3523 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003524 }
3525 }
3526 return false;
3527}
3528
Robert Carr5c8a0262018-10-03 16:30:44 -07003529sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3530 size_t count = mInputChannelsByToken.count(token);
3531 if (count == 0) {
3532 return nullptr;
3533 }
3534 return mInputChannelsByToken.at(token);
3535}
3536
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003537void InputDispatcher::updateWindowHandlesForDisplayLocked(
3538 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3539 if (inputWindowHandles.empty()) {
3540 // Remove all handles on a display if there are no windows left.
3541 mWindowHandlesByDisplay.erase(displayId);
3542 return;
3543 }
3544
3545 // Since we compare the pointer of input window handles across window updates, we need
3546 // to make sure the handle object for the same window stays unchanged across updates.
3547 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003548 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003549 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003550 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003551 }
3552
3553 std::vector<sp<InputWindowHandle>> newHandles;
3554 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3555 if (!handle->updateInfo()) {
3556 // handle no longer valid
3557 continue;
3558 }
3559
3560 const InputWindowInfo* info = handle->getInfo();
3561 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3562 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3563 const bool noInputChannel =
3564 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3565 const bool canReceiveInput =
3566 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3567 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3568 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003569 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003570 handle->getName().c_str());
3571 }
3572 continue;
3573 }
3574
3575 if (info->displayId != displayId) {
3576 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3577 handle->getName().c_str(), displayId, info->displayId);
3578 continue;
3579 }
3580
chaviwaf87b3e2019-10-01 16:59:28 -07003581 if (oldHandlesById.find(handle->getId()) != oldHandlesById.end()) {
3582 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003583 oldHandle->updateFrom(handle);
3584 newHandles.push_back(oldHandle);
3585 } else {
3586 newHandles.push_back(handle);
3587 }
3588 }
3589
3590 // Insert or replace
3591 mWindowHandlesByDisplay[displayId] = newHandles;
3592}
3593
Arthur Hungb92218b2018-08-14 12:00:21 +08003594/**
3595 * Called from InputManagerService, update window handle list by displayId that can receive input.
3596 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3597 * If set an empty list, remove all handles from the specific display.
3598 * For focused handle, check if need to change and send a cancel event to previous one.
3599 * For removed handle, check if need to send a cancel event if already in touch.
3600 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003601void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003602 int32_t displayId,
3603 const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003604 if (DEBUG_FOCUS) {
3605 std::string windowList;
3606 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
3607 windowList += iwh->getName() + " ";
3608 }
3609 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
3610 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003611 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003612 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003613
Arthur Hungb92218b2018-08-14 12:00:21 +08003614 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003615 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3616 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003617
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003618 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3619
Tiger Huang721e26f2018-07-24 22:26:19 +08003620 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003621 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003622 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3623 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3624 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3625 windowHandle->getInfo()->visible) {
3626 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003627 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003628 if (windowHandle == mLastHoverWindowHandle) {
3629 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003630 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003631 }
3632
3633 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003634 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003635 }
3636
Tiger Huang721e26f2018-07-24 22:26:19 +08003637 sp<InputWindowHandle> oldFocusedWindowHandle =
3638 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3639
chaviwaf87b3e2019-10-01 16:59:28 -07003640 if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003641 if (oldFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003642 if (DEBUG_FOCUS) {
3643 ALOGD("Focus left window: %s in display %" PRId32,
3644 oldFocusedWindowHandle->getName().c_str(), displayId);
3645 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003646 sp<InputChannel> focusedInputChannel =
3647 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003648 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003649 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003650 "focus left window");
3651 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003652 enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003653 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003654 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003655 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003656 if (newFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003657 if (DEBUG_FOCUS) {
3658 ALOGD("Focus entered window: %s in display %" PRId32,
3659 newFocusedWindowHandle->getName().c_str(), displayId);
3660 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003661 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003662 enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003663 }
Robert Carrf759f162018-11-13 12:57:11 -08003664
3665 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003666 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003667 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003668 }
3669
Arthur Hungb92218b2018-08-14 12:00:21 +08003670 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3671 if (stateIndex >= 0) {
3672 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003673 for (size_t i = 0; i < state.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003674 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003675 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003676 if (DEBUG_FOCUS) {
3677 ALOGD("Touched window was removed: %s in display %" PRId32,
3678 touchedWindow.windowHandle->getName().c_str(), displayId);
3679 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003680 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003681 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003682 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003683 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003684 "touched window was removed");
3685 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
3686 options);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003687 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003688 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003689 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003690 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003691 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003692 }
3693 }
3694
3695 // Release information for windows that are no longer present.
3696 // This ensures that unused input channels are released promptly.
3697 // Otherwise, they might stick around until the window handle is destroyed
3698 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003699 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003700 if (!hasWindowHandleLocked(oldWindowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003701 if (DEBUG_FOCUS) {
3702 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
3703 }
Arthur Hung3b413f22018-10-26 18:05:34 +08003704 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003705 }
3706 }
3707 } // release lock
3708
3709 // Wake up poll loop since it may need to make new input dispatching choices.
3710 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003711
3712 if (setInputWindowsListener) {
3713 setInputWindowsListener->onSetInputWindowsFinished();
3714 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003715}
3716
3717void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003718 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003719 if (DEBUG_FOCUS) {
3720 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
3721 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
3722 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003723 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003724 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003725
Tiger Huang721e26f2018-07-24 22:26:19 +08003726 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3727 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003728 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003729 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3730 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003731 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003732 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003733 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003734 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003735 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003736 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003737 oldFocusedApplicationHandle.clear();
3738 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003739 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003740 } // release lock
3741
3742 // Wake up poll loop since it may need to make new input dispatching choices.
3743 mLooper->wake();
3744}
3745
Tiger Huang721e26f2018-07-24 22:26:19 +08003746/**
3747 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3748 * the display not specified.
3749 *
3750 * We track any unreleased events for each window. If a window loses the ability to receive the
3751 * released event, we will send a cancel event to it. So when the focused display is changed, we
3752 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3753 * display. The display-specified events won't be affected.
3754 */
3755void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003756 if (DEBUG_FOCUS) {
3757 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3758 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003759 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003760 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003761
3762 if (mFocusedDisplayId != displayId) {
3763 sp<InputWindowHandle> oldFocusedWindowHandle =
3764 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3765 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003766 sp<InputChannel> inputChannel =
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003767 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003768 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003769 CancelationOptions
3770 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3771 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003772 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003773 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3774 }
3775 }
3776 mFocusedDisplayId = displayId;
3777
3778 // Sanity check
3779 sp<InputWindowHandle> newFocusedWindowHandle =
3780 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003781 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003782
Tiger Huang721e26f2018-07-24 22:26:19 +08003783 if (newFocusedWindowHandle == nullptr) {
3784 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3785 if (!mFocusedWindowHandlesByDisplay.empty()) {
3786 ALOGE("But another display has a focused window:");
3787 for (auto& it : mFocusedWindowHandlesByDisplay) {
3788 const int32_t displayId = it.first;
3789 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003790 ALOGE("Display #%" PRId32 " has focused window: '%s'\n", displayId,
3791 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003792 }
3793 }
3794 }
3795 }
3796
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003797 if (DEBUG_FOCUS) {
3798 logDispatchStateLocked();
3799 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003800 } // release lock
3801
3802 // Wake up poll loop since it may need to make new input dispatching choices.
3803 mLooper->wake();
3804}
3805
Michael Wrightd02c5b62014-02-10 15:10:22 -08003806void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003807 if (DEBUG_FOCUS) {
3808 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3809 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003810
3811 bool changed;
3812 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003813 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003814
3815 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3816 if (mDispatchFrozen && !frozen) {
3817 resetANRTimeoutsLocked();
3818 }
3819
3820 if (mDispatchEnabled && !enabled) {
3821 resetAndDropEverythingLocked("dispatcher is being disabled");
3822 }
3823
3824 mDispatchEnabled = enabled;
3825 mDispatchFrozen = frozen;
3826 changed = true;
3827 } else {
3828 changed = false;
3829 }
3830
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003831 if (DEBUG_FOCUS) {
3832 logDispatchStateLocked();
3833 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003834 } // release lock
3835
3836 if (changed) {
3837 // Wake up poll loop since it may need to make new input dispatching choices.
3838 mLooper->wake();
3839 }
3840}
3841
3842void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003843 if (DEBUG_FOCUS) {
3844 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3845 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003846
3847 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003848 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003849
3850 if (mInputFilterEnabled == enabled) {
3851 return;
3852 }
3853
3854 mInputFilterEnabled = enabled;
3855 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3856 } // release lock
3857
3858 // Wake up poll loop since there might be work to do to drop everything.
3859 mLooper->wake();
3860}
3861
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08003862void InputDispatcher::setInTouchMode(bool inTouchMode) {
3863 std::scoped_lock lock(mLock);
3864 mInTouchMode = inTouchMode;
3865}
3866
chaviwfbe5d9c2018-12-26 12:23:37 -08003867bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3868 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003869 if (DEBUG_FOCUS) {
3870 ALOGD("Trivial transfer to same window.");
3871 }
chaviwfbe5d9c2018-12-26 12:23:37 -08003872 return true;
3873 }
3874
Michael Wrightd02c5b62014-02-10 15:10:22 -08003875 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003876 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003877
chaviwfbe5d9c2018-12-26 12:23:37 -08003878 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3879 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003880 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003881 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003882 return false;
3883 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003884 if (DEBUG_FOCUS) {
3885 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3886 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3887 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003888 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003889 if (DEBUG_FOCUS) {
3890 ALOGD("Cannot transfer focus because windows are on different displays.");
3891 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003892 return false;
3893 }
3894
3895 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003896 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3897 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3898 for (size_t i = 0; i < state.windows.size(); i++) {
3899 const TouchedWindow& touchedWindow = state.windows[i];
3900 if (touchedWindow.windowHandle == fromWindowHandle) {
3901 int32_t oldTargetFlags = touchedWindow.targetFlags;
3902 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003903
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003904 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003905
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003906 int32_t newTargetFlags = oldTargetFlags &
3907 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
3908 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003909 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003910
Jeff Brownf086ddb2014-02-11 14:28:48 -08003911 found = true;
3912 goto Found;
3913 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003914 }
3915 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003916 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003917
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003918 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003919 if (DEBUG_FOCUS) {
3920 ALOGD("Focus transfer failed because from window did not have focus.");
3921 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003922 return false;
3923 }
3924
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07003925 sp<Connection> fromConnection = getConnectionLocked(fromToken);
3926 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003927 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003928 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003929 CancelationOptions
3930 options(CancelationOptions::CANCEL_POINTER_EVENTS,
3931 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003932 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003933 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003934 }
3935
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003936 if (DEBUG_FOCUS) {
3937 logDispatchStateLocked();
3938 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003939 } // release lock
3940
3941 // Wake up poll loop since it may need to make new input dispatching choices.
3942 mLooper->wake();
3943 return true;
3944}
3945
3946void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003947 if (DEBUG_FOCUS) {
3948 ALOGD("Resetting and dropping all events (%s).", reason);
3949 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003950
3951 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3952 synthesizeCancelationEventsForAllConnectionsLocked(options);
3953
3954 resetKeyRepeatLocked();
3955 releasePendingEventLocked();
3956 drainInboundQueueLocked();
3957 resetANRTimeoutsLocked();
3958
Jeff Brownf086ddb2014-02-11 14:28:48 -08003959 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003960 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003961 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962}
3963
3964void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003965 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003966 dumpDispatchStateLocked(dump);
3967
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003968 std::istringstream stream(dump);
3969 std::string line;
3970
3971 while (std::getline(stream, line, '\n')) {
3972 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003973 }
3974}
3975
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003976void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003977 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3978 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3979 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003980 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003981
Tiger Huang721e26f2018-07-24 22:26:19 +08003982 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3983 dump += StringPrintf(INDENT "FocusedApplications:\n");
3984 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3985 const int32_t displayId = it.first;
3986 const sp<InputApplicationHandle>& applicationHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003987 dump += StringPrintf(INDENT2 "displayId=%" PRId32
3988 ", name='%s', dispatchingTimeout=%0.3fms\n",
3989 displayId, applicationHandle->getName().c_str(),
3990 applicationHandle->getDispatchingTimeout(
3991 DEFAULT_INPUT_DISPATCHING_TIMEOUT) /
3992 1000000.0);
Tiger Huang721e26f2018-07-24 22:26:19 +08003993 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003994 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003995 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003996 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003997
3998 if (!mFocusedWindowHandlesByDisplay.empty()) {
3999 dump += StringPrintf(INDENT "FocusedWindows:\n");
4000 for (auto& it : mFocusedWindowHandlesByDisplay) {
4001 const int32_t displayId = it.first;
4002 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004003 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
4004 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004005 }
4006 } else {
4007 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
4008 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004009
Jeff Brownf086ddb2014-02-11 14:28:48 -08004010 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004011 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08004012 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
4013 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004014 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004015 state.displayId, toString(state.down), toString(state.split),
4016 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004017 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004018 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004019 for (size_t i = 0; i < state.windows.size(); i++) {
4020 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004021 dump += StringPrintf(INDENT4
4022 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4023 i, touchedWindow.windowHandle->getName().c_str(),
4024 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004025 }
4026 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004027 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004028 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004029 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004030 dump += INDENT3 "Portal windows:\n";
4031 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004032 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004033 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4034 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004035 }
4036 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004037 }
4038 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004039 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004040 }
4041
Arthur Hungb92218b2018-08-14 12:00:21 +08004042 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004043 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004044 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004045 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004046 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004047 dump += INDENT2 "Windows:\n";
4048 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004049 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004050 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004051
Arthur Hungb92218b2018-08-14 12:00:21 +08004052 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004053 "portalToDisplayId=%d, paused=%s, hasFocus=%s, "
chaviwcb923212019-12-30 14:05:11 -08004054 "hasWallpaper=%s, visible=%s, canReceiveKeys=%s, "
4055 "flags=0x%08x, type=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004056 "frame=[%d,%d][%d,%d], globalScale=%f, "
chaviwcb923212019-12-30 14:05:11 -08004057 "windowScale=(%f,%f), touchableRegion=",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004058 i, windowInfo->name.c_str(), windowInfo->displayId,
4059 windowInfo->portalToDisplayId,
4060 toString(windowInfo->paused),
4061 toString(windowInfo->hasFocus),
4062 toString(windowInfo->hasWallpaper),
4063 toString(windowInfo->visible),
4064 toString(windowInfo->canReceiveKeys),
4065 windowInfo->layoutParamsFlags,
chaviwcb923212019-12-30 14:05:11 -08004066 windowInfo->layoutParamsType, windowInfo->frameLeft,
4067 windowInfo->frameTop, windowInfo->frameRight,
4068 windowInfo->frameBottom, windowInfo->globalScaleFactor,
4069 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08004070 dumpRegion(dump, windowInfo->touchableRegion);
4071 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
4072 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004073 windowInfo->ownerPid, windowInfo->ownerUid,
4074 windowInfo->dispatchingTimeout / 1000000.0);
Arthur Hungb92218b2018-08-14 12:00:21 +08004075 }
4076 } else {
4077 dump += INDENT2 "Windows: <none>\n";
4078 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004079 }
4080 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004081 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004082 }
4083
Michael Wright3dd60e22019-03-27 22:06:44 +00004084 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004085 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004086 const std::vector<Monitor>& monitors = it.second;
4087 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4088 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004089 }
4090 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004091 const std::vector<Monitor>& monitors = it.second;
4092 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4093 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004094 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004095 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004096 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004097 }
4098
4099 nsecs_t currentTime = now();
4100
4101 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004102 if (!mRecentQueue.empty()) {
4103 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
4104 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004105 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004106 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004107 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004108 }
4109 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004110 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004111 }
4112
4113 // Dump event currently being dispatched.
4114 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004115 dump += INDENT "PendingEvent:\n";
4116 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004117 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004118 dump += StringPrintf(", age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004119 (currentTime - mPendingEvent->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004120 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004121 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004122 }
4123
4124 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004125 if (!mInboundQueue.empty()) {
4126 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
4127 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004128 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004129 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004130 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004131 }
4132 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004133 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004134 }
4135
Michael Wright78f24442014-08-06 15:55:28 -07004136 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004137 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07004138 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
4139 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
4140 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004141 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n", i,
4142 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004143 }
4144 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004145 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004146 }
4147
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004148 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004149 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004150 for (const auto& pair : mConnectionsByFd) {
4151 const sp<Connection>& connection = pair.second;
4152 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
4153 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
4154 pair.first, connection->getInputChannelName().c_str(),
4155 connection->getWindowName().c_str(), connection->getStatusLabel(),
4156 toString(connection->monitor),
4157 toString(connection->inputPublisherBlocked));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004158
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004159 if (!connection->outboundQueue.empty()) {
4160 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4161 connection->outboundQueue.size());
4162 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004163 dump.append(INDENT4);
4164 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004165 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004166 entry->targetFlags, entry->resolvedAction,
4167 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004168 }
4169 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004170 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004171 }
4172
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004173 if (!connection->waitQueue.empty()) {
4174 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4175 connection->waitQueue.size());
4176 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004177 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004178 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004179 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004180 "age=%0.1fms, wait=%0.1fms\n",
4181 entry->targetFlags, entry->resolvedAction,
4182 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
4183 (currentTime - entry->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004184 }
4185 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004186 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004187 }
4188 }
4189 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004190 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004191 }
4192
4193 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004194 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004195 (mAppSwitchDueTime - now()) / 1000000.0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004196 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004197 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004198 }
4199
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004200 dump += INDENT "Configuration:\n";
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004201 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004202 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004203 mConfig.keyRepeatTimeout * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004204}
4205
Michael Wright3dd60e22019-03-27 22:06:44 +00004206void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4207 const size_t numMonitors = monitors.size();
4208 for (size_t i = 0; i < numMonitors; i++) {
4209 const Monitor& monitor = monitors[i];
4210 const sp<InputChannel>& channel = monitor.inputChannel;
4211 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4212 dump += "\n";
4213 }
4214}
4215
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004216status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004217#if DEBUG_REGISTRATION
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004218 ALOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004219#endif
4220
4221 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004222 std::scoped_lock _l(mLock);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004223 sp<Connection> existingConnection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004224 if (existingConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004225 ALOGW("Attempted to register already registered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004226 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004227 return BAD_VALUE;
4228 }
4229
Michael Wright3dd60e22019-03-27 22:06:44 +00004230 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004231
4232 int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004233 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004234 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004235
Michael Wrightd02c5b62014-02-10 15:10:22 -08004236 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4237 } // release lock
4238
4239 // Wake the looper because some connections have changed.
4240 mLooper->wake();
4241 return OK;
4242}
4243
Michael Wright3dd60e22019-03-27 22:06:44 +00004244status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004245 int32_t displayId, bool isGestureMonitor) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004246 { // acquire lock
4247 std::scoped_lock _l(mLock);
4248
4249 if (displayId < 0) {
4250 ALOGW("Attempted to register input monitor without a specified display.");
4251 return BAD_VALUE;
4252 }
4253
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004254 if (inputChannel->getConnectionToken() == nullptr) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004255 ALOGW("Attempted to register input monitor without an identifying token.");
4256 return BAD_VALUE;
4257 }
4258
4259 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
4260
4261 const int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004262 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004263 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004264
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004265 auto& monitorsByDisplay =
4266 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Michael Wright3dd60e22019-03-27 22:06:44 +00004267 monitorsByDisplay[displayId].emplace_back(inputChannel);
4268
4269 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004270 }
4271 // Wake the looper because some connections have changed.
4272 mLooper->wake();
4273 return OK;
4274}
4275
Michael Wrightd02c5b62014-02-10 15:10:22 -08004276status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
4277#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004278 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004279#endif
4280
4281 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004282 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004283
4284 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
4285 if (status) {
4286 return status;
4287 }
4288 } // release lock
4289
4290 // Wake the poll loop because removing the connection may have changed the current
4291 // synchronization state.
4292 mLooper->wake();
4293 return OK;
4294}
4295
4296status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004297 bool notify) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004298 sp<Connection> connection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004299 if (connection == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004300 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004301 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004302 return BAD_VALUE;
4303 }
4304
John Recke0710582019-09-26 13:46:12 -07004305 [[maybe_unused]] const bool removed = removeByValue(mConnectionsByFd, connection);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004306 ALOG_ASSERT(removed);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004307 mInputChannelsByToken.erase(inputChannel->getConnectionToken());
Robert Carr5c8a0262018-10-03 16:30:44 -07004308
Michael Wrightd02c5b62014-02-10 15:10:22 -08004309 if (connection->monitor) {
4310 removeMonitorChannelLocked(inputChannel);
4311 }
4312
4313 mLooper->removeFd(inputChannel->getFd());
4314
4315 nsecs_t currentTime = now();
4316 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4317
4318 connection->status = Connection::STATUS_ZOMBIE;
4319 return OK;
4320}
4321
4322void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004323 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4324 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4325}
4326
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004327void InputDispatcher::removeMonitorChannelLocked(
4328 const sp<InputChannel>& inputChannel,
Michael Wright3dd60e22019-03-27 22:06:44 +00004329 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004330 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004331 std::vector<Monitor>& monitors = it->second;
4332 const size_t numMonitors = monitors.size();
4333 for (size_t i = 0; i < numMonitors; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004334 if (monitors[i].inputChannel == inputChannel) {
4335 monitors.erase(monitors.begin() + i);
4336 break;
4337 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004338 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004339 if (monitors.empty()) {
4340 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004341 } else {
4342 ++it;
4343 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004344 }
4345}
4346
Michael Wright3dd60e22019-03-27 22:06:44 +00004347status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4348 { // acquire lock
4349 std::scoped_lock _l(mLock);
4350 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4351
4352 if (!foundDisplayId) {
4353 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4354 return BAD_VALUE;
4355 }
4356 int32_t displayId = foundDisplayId.value();
4357
4358 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4359 if (stateIndex < 0) {
4360 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4361 return BAD_VALUE;
4362 }
4363
4364 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4365 std::optional<int32_t> foundDeviceId;
4366 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004367 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004368 foundDeviceId = state.deviceId;
4369 }
4370 }
4371 if (!foundDeviceId || !state.down) {
4372 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004373 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004374 return BAD_VALUE;
4375 }
4376 int32_t deviceId = foundDeviceId.value();
4377
4378 // Send cancel events to all the input channels we're stealing from.
4379 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004380 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004381 options.deviceId = deviceId;
4382 options.displayId = displayId;
4383 for (const TouchedWindow& window : state.windows) {
4384 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004385 if (channel != nullptr) {
4386 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4387 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004388 }
4389 // Then clear the current touch state so we stop dispatching to them as well.
4390 state.filterNonMonitors();
4391 }
4392 return OK;
4393}
4394
Michael Wright3dd60e22019-03-27 22:06:44 +00004395std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4396 const sp<IBinder>& token) {
4397 for (const auto& it : mGestureMonitorsByDisplay) {
4398 const std::vector<Monitor>& monitors = it.second;
4399 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004400 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004401 return it.first;
4402 }
4403 }
4404 }
4405 return std::nullopt;
4406}
4407
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004408sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) {
4409 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004410 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004411 }
4412
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004413 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004414 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004415 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004416 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004417 }
4418 }
Robert Carr4e670e52018-08-15 13:26:12 -07004419
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004420 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004421}
4422
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004423void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4424 const sp<Connection>& connection, uint32_t seq,
4425 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004426 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4427 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004428 commandEntry->connection = connection;
4429 commandEntry->eventTime = currentTime;
4430 commandEntry->seq = seq;
4431 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004432 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004433}
4434
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004435void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4436 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004437 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004438 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004439
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004440 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4441 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004442 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004443 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004444}
4445
chaviw0c06c6e2019-01-09 13:27:07 -08004446void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004447 const sp<InputWindowHandle>& newFocus) {
chaviw0c06c6e2019-01-09 13:27:07 -08004448 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4449 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004450 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4451 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004452 commandEntry->oldToken = oldToken;
4453 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004454 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004455}
4456
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004457void InputDispatcher::onANRLocked(nsecs_t currentTime,
4458 const sp<InputApplicationHandle>& applicationHandle,
4459 const sp<InputWindowHandle>& windowHandle, nsecs_t eventTime,
4460 nsecs_t waitStartTime, const char* reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004461 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4462 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4463 ALOGI("Application is not responding: %s. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004464 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
4465 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), dispatchLatency,
4466 waitDuration, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004467
4468 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004469 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004470 struct tm tm;
4471 localtime_r(&t, &tm);
4472 char timestr[64];
4473 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4474 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004475 mLastANRState += INDENT "ANR:\n";
4476 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004477 mLastANRState +=
4478 StringPrintf(INDENT2 "Window: %s\n",
4479 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004480 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4481 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4482 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004483 dumpDispatchStateLocked(mLastANRState);
4484
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004485 std::unique_ptr<CommandEntry> commandEntry =
4486 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004487 commandEntry->inputApplicationHandle = applicationHandle;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004488 commandEntry->inputChannel =
4489 windowHandle != nullptr ? getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004490 commandEntry->reason = reason;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004491 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004492}
4493
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004494void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004495 mLock.unlock();
4496
4497 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4498
4499 mLock.lock();
4500}
4501
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004502void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004503 sp<Connection> connection = commandEntry->connection;
4504
4505 if (connection->status != Connection::STATUS_ZOMBIE) {
4506 mLock.unlock();
4507
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004508 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004509
4510 mLock.lock();
4511 }
4512}
4513
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004514void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004515 sp<IBinder> oldToken = commandEntry->oldToken;
4516 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004517 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004518 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004519 mLock.lock();
4520}
4521
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004522void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004523 sp<IBinder> token =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004524 commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004525 mLock.unlock();
4526
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004527 nsecs_t newTimeout =
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004528 mPolicy->notifyANR(commandEntry->inputApplicationHandle, token, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004529
4530 mLock.lock();
4531
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004532 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004533}
4534
4535void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4536 CommandEntry* commandEntry) {
4537 KeyEntry* entry = commandEntry->keyEntry;
4538
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004539 KeyEvent event = createKeyEvent(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004540
4541 mLock.unlock();
4542
Michael Wright2b3c3302018-03-02 17:19:13 +00004543 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004544 sp<IBinder> token = commandEntry->inputChannel != nullptr
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004545 ? commandEntry->inputChannel->getConnectionToken()
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004546 : nullptr;
4547 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004548 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4549 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004550 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004551 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004552
4553 mLock.lock();
4554
4555 if (delay < 0) {
4556 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4557 } else if (!delay) {
4558 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4559 } else {
4560 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4561 entry->interceptKeyWakeupTime = now() + delay;
4562 }
4563 entry->release();
4564}
4565
chaviwfd6d3512019-03-25 13:23:49 -07004566void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4567 mLock.unlock();
4568 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4569 mLock.lock();
4570}
4571
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004572void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004573 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004574 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004575 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004576 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004577
4578 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07004579 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004580 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004581 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004582 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004583 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004584
4585 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4586 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4587 std::string msg =
4588 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4589 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4590 dispatchEntry->eventEntry->appendDescription(msg);
4591 ALOGI("%s", msg.c_str());
4592 }
4593
4594 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004595 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004596 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4597 restartEvent =
4598 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004599 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004600 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4601 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4602 handled);
4603 } else {
4604 restartEvent = false;
4605 }
4606
4607 // Dequeue the event and start the next cycle.
4608 // Note that because the lock might have been released, it is possible that the
4609 // contents of the wait queue to have been drained, so we need to double-check
4610 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004611 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4612 if (dispatchEntryIt != connection->waitQueue.end()) {
4613 dispatchEntry = *dispatchEntryIt;
4614 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004615 traceWaitQueueLength(connection);
4616 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004617 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004618 traceOutboundQueueLength(connection);
4619 } else {
4620 releaseDispatchEntry(dispatchEntry);
4621 }
4622 }
4623
4624 // Start the next dispatch cycle for this connection.
4625 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004626}
4627
4628bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004629 DispatchEntry* dispatchEntry,
4630 KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004631 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004632 if (!handled) {
4633 // Report the key as unhandled, since the fallback was not handled.
4634 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4635 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004636 return false;
4637 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004638
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004639 // Get the fallback key state.
4640 // Clear it out after dispatching the UP.
4641 int32_t originalKeyCode = keyEntry->keyCode;
4642 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4643 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4644 connection->inputState.removeFallbackKey(originalKeyCode);
4645 }
4646
4647 if (handled || !dispatchEntry->hasForegroundTarget()) {
4648 // If the application handles the original key for which we previously
4649 // generated a fallback or if the window is not a foreground window,
4650 // then cancel the associated fallback key, if any.
4651 if (fallbackKeyCode != -1) {
4652 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004653#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004654 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004655 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4656 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4657 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004658#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004659 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004660 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004661
4662 mLock.unlock();
4663
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004664 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004665 keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004666
4667 mLock.lock();
4668
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004669 // Cancel the fallback key.
4670 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004671 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004672 "application handled the original non-fallback key "
4673 "or is no longer a foreground target, "
4674 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004675 options.keyCode = fallbackKeyCode;
4676 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004677 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004678 connection->inputState.removeFallbackKey(originalKeyCode);
4679 }
4680 } else {
4681 // If the application did not handle a non-fallback key, first check
4682 // that we are in a good state to perform unhandled key event processing
4683 // Then ask the policy what to do with it.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004684 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN && keyEntry->repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004685 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004686#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004687 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004688 "since this is not an initial down. "
4689 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4690 originalKeyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004691#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004692 return false;
4693 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004694
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004695 // Dispatch the unhandled key to the policy.
4696#if DEBUG_OUTBOUND_EVENT_DETAILS
4697 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004698 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4699 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004700#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004701 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004702
4703 mLock.unlock();
4704
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004705 bool fallback =
4706 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
4707 &event, keyEntry->policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004708
4709 mLock.lock();
4710
4711 if (connection->status != Connection::STATUS_NORMAL) {
4712 connection->inputState.removeFallbackKey(originalKeyCode);
4713 return false;
4714 }
4715
4716 // Latch the fallback keycode for this key on an initial down.
4717 // The fallback keycode cannot change at any other point in the lifecycle.
4718 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004719 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004720 fallbackKeyCode = event.getKeyCode();
4721 } else {
4722 fallbackKeyCode = AKEYCODE_UNKNOWN;
4723 }
4724 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4725 }
4726
4727 ALOG_ASSERT(fallbackKeyCode != -1);
4728
4729 // Cancel the fallback key if the policy decides not to send it anymore.
4730 // We will continue to dispatch the key to the policy but we will no
4731 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004732 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
4733 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004734#if DEBUG_OUTBOUND_EVENT_DETAILS
4735 if (fallback) {
4736 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004737 "as a fallback for %d, but on the DOWN it had requested "
4738 "to send %d instead. Fallback canceled.",
4739 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004740 } else {
4741 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004742 "but on the DOWN it had requested to send %d. "
4743 "Fallback canceled.",
4744 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004745 }
4746#endif
4747
4748 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4749 "canceling fallback, policy no longer desires it");
4750 options.keyCode = fallbackKeyCode;
4751 synthesizeCancelationEventsForConnectionLocked(connection, options);
4752
4753 fallback = false;
4754 fallbackKeyCode = AKEYCODE_UNKNOWN;
4755 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004756 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004757 }
4758 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004759
4760#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004761 {
4762 std::string msg;
4763 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4764 connection->inputState.getFallbackKeys();
4765 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004766 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004767 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004768 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004769 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004770 }
4771#endif
4772
4773 if (fallback) {
4774 // Restart the dispatch cycle using the fallback key.
4775 keyEntry->eventTime = event.getEventTime();
4776 keyEntry->deviceId = event.getDeviceId();
4777 keyEntry->source = event.getSource();
4778 keyEntry->displayId = event.getDisplayId();
4779 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4780 keyEntry->keyCode = fallbackKeyCode;
4781 keyEntry->scanCode = event.getScanCode();
4782 keyEntry->metaState = event.getMetaState();
4783 keyEntry->repeatCount = event.getRepeatCount();
4784 keyEntry->downTime = event.getDownTime();
4785 keyEntry->syntheticRepeat = false;
4786
4787#if DEBUG_OUTBOUND_EVENT_DETAILS
4788 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004789 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4790 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004791#endif
4792 return true; // restart the event
4793 } else {
4794#if DEBUG_OUTBOUND_EVENT_DETAILS
4795 ALOGD("Unhandled key event: No fallback key.");
4796#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004797
4798 // Report the key as unhandled, since there is no fallback key.
4799 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004800 }
4801 }
4802 return false;
4803}
4804
4805bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004806 DispatchEntry* dispatchEntry,
4807 MotionEntry* motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004808 return false;
4809}
4810
4811void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4812 mLock.unlock();
4813
4814 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4815
4816 mLock.lock();
4817}
4818
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004819KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
4820 KeyEvent event;
Garfield Tan4cc839f2020-01-24 11:26:14 -08004821 event.initialize(entry.sequenceNum, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
4822 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
4823 entry.repeatCount, entry.downTime, entry.eventTime);
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004824 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004825}
4826
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004827void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004828 int32_t injectionResult,
4829 nsecs_t timeSpentWaitingForApplication) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004830 // TODO Write some statistics about how long we spend waiting.
4831}
4832
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05004833/**
4834 * Report the touch event latency to the statsd server.
4835 * Input events are reported for statistics if:
4836 * - This is a touchscreen event
4837 * - InputFilter is not enabled
4838 * - Event is not injected or synthesized
4839 *
4840 * Statistics should be reported before calling addValue, to prevent a fresh new sample
4841 * from getting aggregated with the "old" data.
4842 */
4843void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
4844 REQUIRES(mLock) {
4845 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
4846 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
4847 if (!reportForStatistics) {
4848 return;
4849 }
4850
4851 if (mTouchStatistics.shouldReport()) {
4852 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
4853 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
4854 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
4855 mTouchStatistics.reset();
4856 }
4857 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
4858 mTouchStatistics.addValue(latencyMicros);
4859}
4860
Michael Wrightd02c5b62014-02-10 15:10:22 -08004861void InputDispatcher::traceInboundQueueLengthLocked() {
4862 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004863 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004864 }
4865}
4866
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004867void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004868 if (ATRACE_ENABLED()) {
4869 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004870 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004871 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004872 }
4873}
4874
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004875void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004876 if (ATRACE_ENABLED()) {
4877 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004878 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004879 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004880 }
4881}
4882
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004883void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004884 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004885
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004886 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004887 dumpDispatchStateLocked(dump);
4888
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004889 if (!mLastANRState.empty()) {
4890 dump += "\nInput Dispatcher State at time of last ANR:\n";
4891 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004892 }
4893}
4894
4895void InputDispatcher::monitor() {
4896 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004897 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004898 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004899 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004900}
4901
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08004902/**
4903 * Wake up the dispatcher and wait until it processes all events and commands.
4904 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
4905 * this method can be safely called from any thread, as long as you've ensured that
4906 * the work you are interested in completing has already been queued.
4907 */
4908bool InputDispatcher::waitForIdle() {
4909 /**
4910 * Timeout should represent the longest possible time that a device might spend processing
4911 * events and commands.
4912 */
4913 constexpr std::chrono::duration TIMEOUT = 100ms;
4914 std::unique_lock lock(mLock);
4915 mLooper->wake();
4916 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
4917 return result == std::cv_status::no_timeout;
4918}
4919
Garfield Tane84e6f92019-08-29 17:28:41 -07004920} // namespace android::inputdispatcher