blob: 306ed40abb7df49074ef8efd538cac67fb20c524 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
31// Log debug messages about registrations.
32#define DEBUG_REGISTRATION 0
33
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
Siarhei Vishniakou86587282019-09-09 18:20:15 +010038static constexpr bool DEBUG_FOCUS = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -080039
40// Log debug messages about the app switch latency optimization.
41#define DEBUG_APP_SWITCH 0
42
43// Log debug messages about hover events.
44#define DEBUG_HOVER 0
45
46#include "InputDispatcher.h"
47
Garfield Tane84e6f92019-08-29 17:28:41 -070048#include "Connection.h"
49
Michael Wrightd02c5b62014-02-10 15:10:22 -080050#include <errno.h>
Siarhei Vishniakou443ad902019-03-06 17:25:41 -080051#include <inttypes.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080052#include <limits.h>
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -050053#include <statslog.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070054#include <stddef.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080055#include <time.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070056#include <unistd.h>
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -070057#include <queue>
58#include <sstream>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070059
Michael Wright2b3c3302018-03-02 17:19:13 +000060#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080061#include <android-base/stringprintf.h>
Robert Carr4e670e52018-08-15 13:26:12 -070062#include <binder/Binder.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070063#include <log/log.h>
Gang Wang342c9272020-01-13 13:15:04 -050064#include <openssl/hmac.h>
65#include <openssl/rand.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070066#include <powermanager/PowerManager.h>
67#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080068
69#define INDENT " "
70#define INDENT2 " "
71#define INDENT3 " "
72#define INDENT4 " "
73
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080074using android::base::StringPrintf;
75
Garfield Tane84e6f92019-08-29 17:28:41 -070076namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080077
78// Default input dispatching timeout if there is no focused application or paused window
79// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000080constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080081
82// Amount of time to allow for all pending events to be processed when an app switch
83// key is on the way. This is used to preempt input dispatch and drop input events
84// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000085constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080086
87// Amount of time to allow for an event to be dispatched (measured since its eventTime)
88// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000089constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080090
91// Amount of time to allow touch events to be streamed out to a connection before requiring
92// that the first event be finished. This value extends the ANR timeout by the specified
93// amount. For example, if streaming is allowed to get ahead by one second relative to the
94// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000095constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080096
97// 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 +000098constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
99
100// Log a warning when an interception call takes longer than this to process.
101constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800102
103// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000104constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
105
Michael Wrightd02c5b62014-02-10 15:10:22 -0800106static inline nsecs_t now() {
107 return systemTime(SYSTEM_TIME_MONOTONIC);
108}
109
110static inline const char* toString(bool value) {
111 return value ? "true" : "false";
112}
113
114static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700115 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
116 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800117}
118
119static bool isValidKeyAction(int32_t action) {
120 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700121 case AKEY_EVENT_ACTION_DOWN:
122 case AKEY_EVENT_ACTION_UP:
123 return true;
124 default:
125 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800126 }
127}
128
129static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700130 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800131 ALOGE("Key event has invalid action code 0x%x", action);
132 return false;
133 }
134 return true;
135}
136
Michael Wright7b159c92015-05-14 14:48:03 +0100137static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800138 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700139 case AMOTION_EVENT_ACTION_DOWN:
140 case AMOTION_EVENT_ACTION_UP:
141 case AMOTION_EVENT_ACTION_CANCEL:
142 case AMOTION_EVENT_ACTION_MOVE:
143 case AMOTION_EVENT_ACTION_OUTSIDE:
144 case AMOTION_EVENT_ACTION_HOVER_ENTER:
145 case AMOTION_EVENT_ACTION_HOVER_MOVE:
146 case AMOTION_EVENT_ACTION_HOVER_EXIT:
147 case AMOTION_EVENT_ACTION_SCROLL:
148 return true;
149 case AMOTION_EVENT_ACTION_POINTER_DOWN:
150 case AMOTION_EVENT_ACTION_POINTER_UP: {
151 int32_t index = getMotionEventActionPointerIndex(action);
152 return index >= 0 && index < pointerCount;
153 }
154 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
155 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
156 return actionButton != 0;
157 default:
158 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800159 }
160}
161
Michael Wright7b159c92015-05-14 14:48:03 +0100162static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700163 const PointerProperties* pointerProperties) {
164 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800165 ALOGE("Motion event has invalid action code 0x%x", action);
166 return false;
167 }
168 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000169 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700170 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800171 return false;
172 }
173 BitSet32 pointerIdBits;
174 for (size_t i = 0; i < pointerCount; i++) {
175 int32_t id = pointerProperties[i].id;
176 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700177 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
178 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800179 return false;
180 }
181 if (pointerIdBits.hasBit(id)) {
182 ALOGE("Motion event has duplicate pointer id %d", id);
183 return false;
184 }
185 pointerIdBits.markBit(id);
186 }
187 return true;
188}
189
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800190static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800191 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800192 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800193 return;
194 }
195
196 bool first = true;
197 Region::const_iterator cur = region.begin();
198 Region::const_iterator const tail = region.end();
199 while (cur != tail) {
200 if (first) {
201 first = false;
202 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800203 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800205 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800206 cur++;
207 }
208}
209
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700210/**
211 * Find the entry in std::unordered_map by key, and return it.
212 * If the entry is not found, return a default constructed entry.
213 *
214 * Useful when the entries are vectors, since an empty vector will be returned
215 * if the entry is not found.
216 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
217 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700218template <typename K, typename V>
219static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700220 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700221 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800222}
223
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700224/**
225 * Find the entry in std::unordered_map by value, and remove it.
226 * If more than one entry has the same value, then all matching
227 * key-value pairs will be removed.
228 *
229 * Return true if at least one value has been removed.
230 */
231template <typename K, typename V>
232static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
233 bool removed = false;
234 for (auto it = map.begin(); it != map.end();) {
235 if (it->second == value) {
236 it = map.erase(it);
237 removed = true;
238 } else {
239 it++;
240 }
241 }
242 return removed;
243}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800244
chaviwaf87b3e2019-10-01 16:59:28 -0700245static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
246 if (first == second) {
247 return true;
248 }
249
250 if (first == nullptr || second == nullptr) {
251 return false;
252 }
253
254 return first->getToken() == second->getToken();
255}
256
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800257static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
258 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
259}
260
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000261static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
262 EventEntry* eventEntry,
263 int32_t inputTargetFlags) {
264 if (inputTarget.useDefaultPointerInfo()) {
265 const PointerInfo& pointerInfo = inputTarget.getDefaultPointerInfo();
266 return std::make_unique<DispatchEntry>(eventEntry, // increments ref
267 inputTargetFlags, pointerInfo.xOffset,
268 pointerInfo.yOffset, inputTarget.globalScaleFactor,
269 pointerInfo.windowXScale, pointerInfo.windowYScale);
270 }
271
272 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
273 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
274
275 PointerCoords pointerCoords[motionEntry.pointerCount];
276
277 // Use the first pointer information to normalize all other pointers. This could be any pointer
278 // as long as all other pointers are normalized to the same value and the final DispatchEntry
279 // uses the offset and scale for the normalized pointer.
280 const PointerInfo& firstPointerInfo =
281 inputTarget.pointerInfos[inputTarget.pointerIds.firstMarkedBit()];
282
283 // Iterate through all pointers in the event to normalize against the first.
284 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
285 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
286 uint32_t pointerId = uint32_t(pointerProperties.id);
287 const PointerInfo& currPointerInfo = inputTarget.pointerInfos[pointerId];
288
289 // The scale factor is the ratio of the current pointers scale to the normalized scale.
290 float scaleXDiff = currPointerInfo.windowXScale / firstPointerInfo.windowXScale;
291 float scaleYDiff = currPointerInfo.windowYScale / firstPointerInfo.windowYScale;
292
293 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
294 // First apply the current pointers offset to set the window at 0,0
295 pointerCoords[pointerIndex].applyOffset(currPointerInfo.xOffset, currPointerInfo.yOffset);
296 // Next scale the coordinates.
297 pointerCoords[pointerIndex].scale(1, scaleXDiff, scaleYDiff);
298 // Lastly, offset the coordinates so they're in the normalized pointer's frame.
299 pointerCoords[pointerIndex].applyOffset(-firstPointerInfo.xOffset,
300 -firstPointerInfo.yOffset);
301 }
302
303 MotionEntry* combinedMotionEntry =
304 new MotionEntry(motionEntry.sequenceNum, motionEntry.eventTime, motionEntry.deviceId,
305 motionEntry.source, motionEntry.displayId, motionEntry.policyFlags,
306 motionEntry.action, motionEntry.actionButton, motionEntry.flags,
307 motionEntry.metaState, motionEntry.buttonState,
308 motionEntry.classification, motionEntry.edgeFlags,
309 motionEntry.xPrecision, motionEntry.yPrecision,
310 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
311 motionEntry.downTime, motionEntry.pointerCount,
312 motionEntry.pointerProperties, pointerCoords, 0 /* xOffset */,
313 0 /* yOffset */);
314
315 if (motionEntry.injectionState) {
316 combinedMotionEntry->injectionState = motionEntry.injectionState;
317 combinedMotionEntry->injectionState->refCount += 1;
318 }
319
320 std::unique_ptr<DispatchEntry> dispatchEntry =
321 std::make_unique<DispatchEntry>(combinedMotionEntry, // increments ref
322 inputTargetFlags, firstPointerInfo.xOffset,
323 firstPointerInfo.yOffset, inputTarget.globalScaleFactor,
324 firstPointerInfo.windowXScale,
325 firstPointerInfo.windowYScale);
326 combinedMotionEntry->release();
327 return dispatchEntry;
328}
329
Gang Wang342c9272020-01-13 13:15:04 -0500330static std::array<uint8_t, 128> getRandomKey() {
331 std::array<uint8_t, 128> key;
332 if (RAND_bytes(key.data(), key.size()) != 1) {
333 LOG_ALWAYS_FATAL("Can't generate HMAC key");
334 }
335 return key;
336}
337
338// --- HmacKeyManager ---
339
340HmacKeyManager::HmacKeyManager() : mHmacKey(getRandomKey()) {}
341
342std::array<uint8_t, 32> HmacKeyManager::sign(const VerifiedInputEvent& event) const {
343 size_t size;
344 switch (event.type) {
345 case VerifiedInputEvent::Type::KEY: {
346 size = sizeof(VerifiedKeyEvent);
347 break;
348 }
349 case VerifiedInputEvent::Type::MOTION: {
350 size = sizeof(VerifiedMotionEvent);
351 break;
352 }
353 }
354 std::vector<uint8_t> data;
355 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
356 data.assign(start, start + size);
357 return sign(data);
358}
359
360std::array<uint8_t, 32> HmacKeyManager::sign(const std::vector<uint8_t>& data) const {
361 // SHA256 always generates 32-bytes result
362 std::array<uint8_t, 32> hash;
363 unsigned int hashLen = 0;
364 uint8_t* result = HMAC(EVP_sha256(), mHmacKey.data(), mHmacKey.size(), data.data(), data.size(),
365 hash.data(), &hashLen);
366 if (result == nullptr) {
367 ALOGE("Could not sign the data using HMAC");
368 return INVALID_HMAC;
369 }
370
371 if (hashLen != hash.size()) {
372 ALOGE("HMAC-SHA256 has unexpected length");
373 return INVALID_HMAC;
374 }
375
376 return hash;
377}
378
Michael Wrightd02c5b62014-02-10 15:10:22 -0800379// --- InputDispatcher ---
380
Garfield Tan00f511d2019-06-12 16:55:40 -0700381InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
382 : mPolicy(policy),
383 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700384 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tan00f511d2019-06-12 16:55:40 -0700385 mAppSwitchSawKeyDown(false),
386 mAppSwitchDueTime(LONG_LONG_MAX),
387 mNextUnblockedEvent(nullptr),
388 mDispatchEnabled(false),
389 mDispatchFrozen(false),
390 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800391 // mInTouchMode will be initialized by the WindowManager to the default device config.
392 // To avoid leaking stack in case that call never comes, and for tests,
393 // initialize it here anyways.
394 mInTouchMode(true),
Garfield Tan00f511d2019-06-12 16:55:40 -0700395 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
396 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800397 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800398 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800399
Yi Kong9b14ac62018-07-17 13:48:38 -0700400 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800401
402 policy->getDispatcherConfiguration(&mConfig);
403}
404
405InputDispatcher::~InputDispatcher() {
406 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800407 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800408
409 resetKeyRepeatLocked();
410 releasePendingEventLocked();
411 drainInboundQueueLocked();
412 }
413
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700414 while (!mConnectionsByFd.empty()) {
415 sp<Connection> connection = mConnectionsByFd.begin()->second;
416 unregisterInputChannel(connection->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800417 }
418}
419
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700420status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700421 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700422 return ALREADY_EXISTS;
423 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700424 mThread = std::make_unique<InputThread>(
425 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
426 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700427}
428
429status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700430 if (mThread && mThread->isCallingThread()) {
431 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700432 return INVALID_OPERATION;
433 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700434 mThread.reset();
435 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700436}
437
Michael Wrightd02c5b62014-02-10 15:10:22 -0800438void InputDispatcher::dispatchOnce() {
439 nsecs_t nextWakeupTime = LONG_LONG_MAX;
440 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800441 std::scoped_lock _l(mLock);
442 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800443
444 // Run a dispatch loop if there are no pending commands.
445 // The dispatch loop might enqueue commands to run afterwards.
446 if (!haveCommandsLocked()) {
447 dispatchOnceInnerLocked(&nextWakeupTime);
448 }
449
450 // Run all pending commands if there are any.
451 // If any commands were run then force the next poll to wake up immediately.
452 if (runCommandsLockedInterruptible()) {
453 nextWakeupTime = LONG_LONG_MIN;
454 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800455
456 // We are about to enter an infinitely long sleep, because we have no commands or
457 // pending or queued events
458 if (nextWakeupTime == LONG_LONG_MAX) {
459 mDispatcherEnteredIdle.notify_all();
460 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800461 } // release lock
462
463 // Wait for callback or timeout or wake. (make sure we round up, not down)
464 nsecs_t currentTime = now();
465 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
466 mLooper->pollOnce(timeoutMillis);
467}
468
469void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
470 nsecs_t currentTime = now();
471
Jeff Browndc5992e2014-04-11 01:27:26 -0700472 // Reset the key repeat timer whenever normal dispatch is suspended while the
473 // device is in a non-interactive state. This is to ensure that we abort a key
474 // repeat if the device is just coming out of sleep.
475 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800476 resetKeyRepeatLocked();
477 }
478
479 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
480 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100481 if (DEBUG_FOCUS) {
482 ALOGD("Dispatch frozen. Waiting some more.");
483 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800484 return;
485 }
486
487 // Optimize latency of app switches.
488 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
489 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
490 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
491 if (mAppSwitchDueTime < *nextWakeupTime) {
492 *nextWakeupTime = mAppSwitchDueTime;
493 }
494
495 // Ready to start a new event.
496 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700497 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700498 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800499 if (isAppSwitchDue) {
500 // The inbound queue is empty so the app switch key we were waiting
501 // for will never arrive. Stop waiting for it.
502 resetPendingAppSwitchLocked(false);
503 isAppSwitchDue = false;
504 }
505
506 // Synthesize a key repeat if appropriate.
507 if (mKeyRepeatState.lastKeyEntry) {
508 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
509 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
510 } else {
511 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
512 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
513 }
514 }
515 }
516
517 // Nothing to do if there is no pending event.
518 if (!mPendingEvent) {
519 return;
520 }
521 } else {
522 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700523 mPendingEvent = mInboundQueue.front();
524 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800525 traceInboundQueueLengthLocked();
526 }
527
528 // Poke user activity for this event.
529 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700530 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800531 }
532
533 // Get ready to dispatch the event.
534 resetANRTimeoutsLocked();
535 }
536
537 // Now we have an event to dispatch.
538 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700539 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800540 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700541 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800542 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700543 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800544 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700545 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800546 }
547
548 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700549 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800550 }
551
552 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700553 case EventEntry::Type::CONFIGURATION_CHANGED: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700554 ConfigurationChangedEntry* typedEntry =
555 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
556 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700557 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700558 break;
559 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800560
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700561 case EventEntry::Type::DEVICE_RESET: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700562 DeviceResetEntry* typedEntry = static_cast<DeviceResetEntry*>(mPendingEvent);
563 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700564 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700565 break;
566 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800567
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100568 case EventEntry::Type::FOCUS: {
569 FocusEntry* typedEntry = static_cast<FocusEntry*>(mPendingEvent);
570 dispatchFocusLocked(currentTime, typedEntry);
571 done = true;
572 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
573 break;
574 }
575
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700576 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700577 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
578 if (isAppSwitchDue) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700579 if (isAppSwitchKeyEvent(*typedEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700580 resetPendingAppSwitchLocked(true);
581 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700582 } else if (dropReason == DropReason::NOT_DROPPED) {
583 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700584 }
585 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700586 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700587 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700588 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700589 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
590 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700591 }
592 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
593 break;
594 }
595
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700596 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700597 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700598 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
599 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800600 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700601 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700602 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700603 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700604 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
605 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700606 }
607 done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
608 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800609 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800610 }
611
612 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700613 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700614 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800615 }
Michael Wright3a981722015-06-10 15:26:13 +0100616 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800617
618 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700619 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800620 }
621}
622
623bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700624 bool needWake = mInboundQueue.empty();
625 mInboundQueue.push_back(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800626 traceInboundQueueLengthLocked();
627
628 switch (entry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700629 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700630 // Optimize app switch latency.
631 // If the application takes too long to catch up then we drop all events preceding
632 // the app switch key.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700633 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700634 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700635 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700636 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700637 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700638 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800639#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700640 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800641#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700642 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700643 mAppSwitchSawKeyDown = false;
644 needWake = true;
645 }
646 }
647 }
648 break;
649 }
650
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700651 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700652 // Optimize case where the current application is unresponsive and the user
653 // decides to touch a window in a different application.
654 // If the application takes too long to catch up then we drop all events preceding
655 // the touch into the other window.
656 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
657 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN &&
658 (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
659 mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY &&
660 mInputTargetWaitApplicationToken != nullptr) {
661 int32_t displayId = motionEntry->displayId;
662 int32_t x =
663 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
664 int32_t y =
665 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
666 sp<InputWindowHandle> touchedWindowHandle =
667 findTouchedWindowAtLocked(displayId, x, y);
668 if (touchedWindowHandle != nullptr &&
669 touchedWindowHandle->getApplicationToken() !=
670 mInputTargetWaitApplicationToken) {
671 // User touched a different application than the one we are waiting on.
672 // Flag the event, and start pruning the input queue.
673 mNextUnblockedEvent = motionEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800674 needWake = true;
675 }
676 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700677 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800678 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700679 case EventEntry::Type::CONFIGURATION_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100680 case EventEntry::Type::DEVICE_RESET:
681 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700682 // nothing to do
683 break;
684 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800685 }
686
687 return needWake;
688}
689
690void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
691 entry->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700692 mRecentQueue.push_back(entry);
693 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
694 mRecentQueue.front()->release();
695 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800696 }
697}
698
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700699sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
700 int32_t y, bool addOutsideTargets,
701 bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800702 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800703 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
704 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800705 const InputWindowInfo* windowInfo = windowHandle->getInfo();
706 if (windowInfo->displayId == displayId) {
707 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800708
709 if (windowInfo->visible) {
710 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700711 bool isTouchModal = (flags &
712 (InputWindowInfo::FLAG_NOT_FOCUSABLE |
713 InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800714 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800715 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700716 if (portalToDisplayId != ADISPLAY_ID_NONE &&
717 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800718 if (addPortalWindows) {
719 // For the monitoring channels of the display.
720 mTempTouchState.addPortalWindow(windowHandle);
721 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700722 return findTouchedWindowAtLocked(portalToDisplayId, x, y,
723 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800724 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800725 // Found window.
726 return windowHandle;
727 }
728 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800729
730 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700731 mTempTouchState.addOrUpdateWindow(windowHandle,
732 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
733 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800734 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800735 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800736 }
737 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700738 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800739}
740
Garfield Tane84e6f92019-08-29 17:28:41 -0700741std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +0000742 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
743 std::vector<TouchedMonitor> touchedMonitors;
744
745 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
746 addGestureMonitors(monitors, touchedMonitors);
747 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
748 const InputWindowInfo* windowInfo = portalWindow->getInfo();
749 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700750 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
751 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000752 }
753 return touchedMonitors;
754}
755
756void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700757 std::vector<TouchedMonitor>& outTouchedMonitors,
758 float xOffset, float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000759 if (monitors.empty()) {
760 return;
761 }
762 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
763 for (const Monitor& monitor : monitors) {
764 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
765 }
766}
767
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700768void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800769 const char* reason;
770 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700771 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800772#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700773 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800774#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700775 reason = "inbound event was dropped because the policy consumed it";
776 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700777 case DropReason::DISABLED:
778 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700779 ALOGI("Dropped event because input dispatch is disabled.");
780 }
781 reason = "inbound event was dropped because input dispatch is disabled";
782 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700783 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700784 ALOGI("Dropped event because of pending overdue app switch.");
785 reason = "inbound event was dropped because of pending overdue app switch";
786 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700787 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700788 ALOGI("Dropped event because the current application is not responding and the user "
789 "has started interacting with a different application.");
790 reason = "inbound event was dropped because the current application is not responding "
791 "and the user has started interacting with a different application";
792 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700793 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700794 ALOGI("Dropped event because it is stale.");
795 reason = "inbound event was dropped because it is stale";
796 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700797 case DropReason::NOT_DROPPED: {
798 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700799 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700800 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800801 }
802
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700803 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700804 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800805 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
806 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700807 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800808 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700809 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700810 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
811 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700812 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
813 synthesizeCancelationEventsForAllConnectionsLocked(options);
814 } else {
815 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
816 synthesizeCancelationEventsForAllConnectionsLocked(options);
817 }
818 break;
819 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100820 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700821 case EventEntry::Type::CONFIGURATION_CHANGED:
822 case EventEntry::Type::DEVICE_RESET: {
823 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
824 break;
825 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800826 }
827}
828
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800829static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700830 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
831 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800832}
833
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700834bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
835 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
836 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
837 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800838}
839
840bool InputDispatcher::isAppSwitchPendingLocked() {
841 return mAppSwitchDueTime != LONG_LONG_MAX;
842}
843
844void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
845 mAppSwitchDueTime = LONG_LONG_MAX;
846
847#if DEBUG_APP_SWITCH
848 if (handled) {
849 ALOGD("App switch has arrived.");
850 } else {
851 ALOGD("App switch was abandoned.");
852 }
853#endif
854}
855
Michael Wrightd02c5b62014-02-10 15:10:22 -0800856bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700857 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800858}
859
860bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700861 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800862 return false;
863 }
864
865 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700866 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700867 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800868 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700869 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800870
871 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700872 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800873 return true;
874}
875
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700876void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
877 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800878}
879
880void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700881 while (!mInboundQueue.empty()) {
882 EventEntry* entry = mInboundQueue.front();
883 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800884 releaseInboundEventLocked(entry);
885 }
886 traceInboundQueueLengthLocked();
887}
888
889void InputDispatcher::releasePendingEventLocked() {
890 if (mPendingEvent) {
891 resetANRTimeoutsLocked();
892 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700893 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800894 }
895}
896
897void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
898 InjectionState* injectionState = entry->injectionState;
899 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
900#if DEBUG_DISPATCH_CYCLE
901 ALOGD("Injected inbound event was dropped.");
902#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800903 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800904 }
905 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700906 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800907 }
908 addRecentEventLocked(entry);
909 entry->release();
910}
911
912void InputDispatcher::resetKeyRepeatLocked() {
913 if (mKeyRepeatState.lastKeyEntry) {
914 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700915 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800916 }
917}
918
Garfield Tane84e6f92019-08-29 17:28:41 -0700919KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800920 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
921
922 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700923 uint32_t policyFlags = entry->policyFlags &
924 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800925 if (entry->refCount == 1) {
926 entry->recycle();
927 entry->eventTime = currentTime;
928 entry->policyFlags = policyFlags;
929 entry->repeatCount += 1;
930 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700931 KeyEntry* newEntry =
932 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, entry->deviceId,
933 entry->source, entry->displayId, policyFlags, entry->action,
934 entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
935 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800936
937 mKeyRepeatState.lastKeyEntry = newEntry;
938 entry->release();
939
940 entry = newEntry;
941 }
942 entry->syntheticRepeat = true;
943
944 // Increment reference count since we keep a reference to the event in
945 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
946 entry->refCount += 1;
947
948 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
949 return entry;
950}
951
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700952bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
953 ConfigurationChangedEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800954#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700955 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800956#endif
957
958 // Reset key repeating in case a keyboard device was added or removed or something.
959 resetKeyRepeatLocked();
960
961 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700962 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
963 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800964 commandEntry->eventTime = entry->eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700965 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800966 return true;
967}
968
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700969bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceResetEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800970#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700971 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700972 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800973#endif
974
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700975 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800976 options.deviceId = entry->deviceId;
977 synthesizeCancelationEventsForAllConnectionsLocked(options);
978 return true;
979}
980
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100981void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) {
982 FocusEntry* focusEntry =
983 new FocusEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, now(), window.getToken(), hasFocus);
984 enqueueInboundEventLocked(focusEntry);
985}
986
987void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) {
988 sp<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
989 if (channel == nullptr) {
990 return; // Window has gone away
991 }
992 InputTarget target;
993 target.inputChannel = channel;
994 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
995 entry->dispatchInProgress = true;
996
997 dispatchEventLocked(currentTime, entry, {target});
998}
999
Michael Wrightd02c5b62014-02-10 15:10:22 -08001000bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001001 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001002 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001003 if (!entry->dispatchInProgress) {
1004 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1005 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1006 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1007 if (mKeyRepeatState.lastKeyEntry &&
1008 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001009 // We have seen two identical key downs in a row which indicates that the device
1010 // driver is automatically generating key repeats itself. We take note of the
1011 // repeat here, but we disable our own next key repeat timer since it is clear that
1012 // we will not need to synthesize key repeats ourselves.
1013 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1014 resetKeyRepeatLocked();
1015 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1016 } else {
1017 // Not a repeat. Save key down state in case we do see a repeat later.
1018 resetKeyRepeatLocked();
1019 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1020 }
1021 mKeyRepeatState.lastKeyEntry = entry;
1022 entry->refCount += 1;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001023 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001024 resetKeyRepeatLocked();
1025 }
1026
1027 if (entry->repeatCount == 1) {
1028 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1029 } else {
1030 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1031 }
1032
1033 entry->dispatchInProgress = true;
1034
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001035 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001036 }
1037
1038 // Handle case where the policy asked us to try again later last time.
1039 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1040 if (currentTime < entry->interceptKeyWakeupTime) {
1041 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1042 *nextWakeupTime = entry->interceptKeyWakeupTime;
1043 }
1044 return false; // wait until next wakeup
1045 }
1046 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1047 entry->interceptKeyWakeupTime = 0;
1048 }
1049
1050 // Give the policy a chance to intercept the key.
1051 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1052 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001053 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001054 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +08001055 sp<InputWindowHandle> focusedWindowHandle =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001056 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(*entry));
Tiger Huang721e26f2018-07-24 22:26:19 +08001057 if (focusedWindowHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001058 commandEntry->inputChannel = getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001059 }
1060 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001061 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001062 entry->refCount += 1;
1063 return false; // wait for the command to run
1064 } else {
1065 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1066 }
1067 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001068 if (*dropReason == DropReason::NOT_DROPPED) {
1069 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001070 }
1071 }
1072
1073 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001074 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001075 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001076 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001077 : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08001078 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001079 return true;
1080 }
1081
1082 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001083 std::vector<InputTarget> inputTargets;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001084 int32_t injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001085 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001086 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1087 return false;
1088 }
1089
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001090 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001091 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
1092 return true;
1093 }
1094
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001095 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001096 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001097
1098 // Dispatch the key.
1099 dispatchEventLocked(currentTime, entry, inputTargets);
1100 return true;
1101}
1102
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001103void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001104#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001105 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001106 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1107 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001108 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1109 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1110 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001111#endif
1112}
1113
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001114bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry,
1115 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001116 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001117 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001118 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001119 entry->dispatchInProgress = true;
1120
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001121 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001122 }
1123
1124 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001125 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001126 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001127 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001128 : INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001129 return true;
1130 }
1131
1132 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1133
1134 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001135 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001136
1137 bool conflictingPointerActions = false;
1138 int32_t injectionResult;
1139 if (isPointerEvent) {
1140 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001141 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001142 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001143 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001144 } else {
1145 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001146 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001147 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001148 }
1149 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1150 return false;
1151 }
1152
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001153 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001154 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001155 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001156 CancelationOptions::Mode mode(isPointerEvent
1157 ? CancelationOptions::CANCEL_POINTER_EVENTS
1158 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001159 CancelationOptions options(mode, "input event injection failed");
1160 synthesizeCancelationEventsForMonitorsLocked(options);
1161 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001162 return true;
1163 }
1164
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001165 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001166 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001167
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001168 if (isPointerEvent) {
1169 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1170 if (stateIndex >= 0) {
1171 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001172 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001173 // The event has gone through these portal windows, so we add monitoring targets of
1174 // the corresponding displays as well.
1175 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001176 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001177 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001178 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001179 }
1180 }
1181 }
1182 }
1183
Michael Wrightd02c5b62014-02-10 15:10:22 -08001184 // Dispatch the motion.
1185 if (conflictingPointerActions) {
1186 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001187 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001188 synthesizeCancelationEventsForAllConnectionsLocked(options);
1189 }
1190 dispatchEventLocked(currentTime, entry, inputTargets);
1191 return true;
1192}
1193
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001194void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001195#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001196 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001197 ", policyFlags=0x%x, "
1198 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1199 "metaState=0x%x, buttonState=0x%x,"
1200 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001201 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1202 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1203 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001204
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001205 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001206 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001207 "x=%f, y=%f, pressure=%f, size=%f, "
1208 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1209 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001210 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1211 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1212 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1213 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1214 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1215 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1216 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1217 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1218 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1219 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001220 }
1221#endif
1222}
1223
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001224void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* eventEntry,
1225 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001226 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001227#if DEBUG_DISPATCH_CYCLE
1228 ALOGD("dispatchEventToCurrentInputTargets");
1229#endif
1230
1231 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1232
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001233 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001234
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001235 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001236 sp<Connection> connection =
1237 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001238 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001239 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001240 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001241 if (DEBUG_FOCUS) {
1242 ALOGD("Dropping event delivery to target with channel '%s' because it "
1243 "is no longer registered with the input dispatcher.",
1244 inputTarget.inputChannel->getName().c_str());
1245 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001246 }
1247 }
1248}
1249
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001250int32_t InputDispatcher::handleTargetsNotReadyLocked(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001251 nsecs_t currentTime, const EventEntry& entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001252 const sp<InputApplicationHandle>& applicationHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001253 const sp<InputWindowHandle>& windowHandle, nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001254 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001255 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001256 if (DEBUG_FOCUS) {
1257 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1258 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001259 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1260 mInputTargetWaitStartTime = currentTime;
1261 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1262 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001263 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001264 }
1265 } else {
1266 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001267 if (DEBUG_FOCUS) {
1268 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
1269 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), reason);
1270 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001271 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001272 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001273 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001274 } else if (applicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001275 timeout =
1276 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001277 } else {
1278 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1279 }
1280
1281 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1282 mInputTargetWaitStartTime = currentTime;
1283 mInputTargetWaitTimeoutTime = currentTime + timeout;
1284 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001285 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001286
Yi Kong9b14ac62018-07-17 13:48:38 -07001287 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001288 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001289 }
Robert Carr740167f2018-10-11 19:03:41 -07001290 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1291 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001292 }
1293 }
1294 }
1295
1296 if (mInputTargetWaitTimeoutExpired) {
1297 return INPUT_EVENT_INJECTION_TIMED_OUT;
1298 }
1299
1300 if (currentTime >= mInputTargetWaitTimeoutTime) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001301 onANRLocked(currentTime, applicationHandle, windowHandle, entry.eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001302 mInputTargetWaitStartTime, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001303
1304 // Force poll loop to wake up immediately on next iteration once we get the
1305 // ANR response back from the policy.
1306 *nextWakeupTime = LONG_LONG_MIN;
1307 return INPUT_EVENT_INJECTION_PENDING;
1308 } else {
1309 // Force poll loop to wake up when timeout is due.
1310 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1311 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1312 }
1313 return INPUT_EVENT_INJECTION_PENDING;
1314 }
1315}
1316
Robert Carr803535b2018-08-02 16:38:15 -07001317void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1318 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1319 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1320 state.removeWindowByToken(token);
1321 }
1322}
1323
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001324void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001325 nsecs_t newTimeout, const sp<IBinder>& inputConnectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001326 if (newTimeout > 0) {
1327 // Extend the timeout.
1328 mInputTargetWaitTimeoutTime = now() + newTimeout;
1329 } else {
1330 // Give up.
1331 mInputTargetWaitTimeoutExpired = true;
1332
1333 // Input state will not be realistic. Mark it out of sync.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001334 sp<Connection> connection = getConnectionLocked(inputConnectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001335 if (connection != nullptr) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07001336 removeWindowByTokenLocked(inputConnectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001337
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001338 if (connection->status == Connection::STATUS_NORMAL) {
1339 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1340 "application not responding");
1341 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001342 }
1343 }
1344 }
1345}
1346
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001347nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001348 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1349 return currentTime - mInputTargetWaitStartTime;
1350 }
1351 return 0;
1352}
1353
1354void InputDispatcher::resetANRTimeoutsLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001355 if (DEBUG_FOCUS) {
1356 ALOGD("Resetting ANR timeouts.");
1357 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001358
1359 // Reset input target wait timeout.
1360 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001361 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001362}
1363
Tiger Huang721e26f2018-07-24 22:26:19 +08001364/**
1365 * Get the display id that the given event should go to. If this event specifies a valid display id,
1366 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1367 * Focused display is the display that the user most recently interacted with.
1368 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001369int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001370 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001371 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001372 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001373 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1374 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001375 break;
1376 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001377 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001378 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1379 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001380 break;
1381 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001382 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001383 case EventEntry::Type::CONFIGURATION_CHANGED:
1384 case EventEntry::Type::DEVICE_RESET: {
1385 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001386 return ADISPLAY_ID_NONE;
1387 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001388 }
1389 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1390}
1391
Michael Wrightd02c5b62014-02-10 15:10:22 -08001392int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001393 const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001394 std::vector<InputTarget>& inputTargets,
1395 nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001396 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001397 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001398
Tiger Huang721e26f2018-07-24 22:26:19 +08001399 int32_t displayId = getTargetDisplayId(entry);
1400 sp<InputWindowHandle> focusedWindowHandle =
1401 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1402 sp<InputApplicationHandle> focusedApplicationHandle =
1403 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1404
Michael Wrightd02c5b62014-02-10 15:10:22 -08001405 // If there is no currently focused window and no focused application
1406 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001407 if (focusedWindowHandle == nullptr) {
1408 if (focusedApplicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001409 injectionResult =
1410 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1411 nullptr, nextWakeupTime,
1412 "Waiting because no window has focus but there is "
1413 "a focused application that may eventually add a "
1414 "window when it finishes starting up.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001415 goto Unresponsive;
1416 }
1417
Arthur Hung3b413f22018-10-26 18:05:34 +08001418 ALOGI("Dropping event because there is no focused window or focused application in display "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001419 "%" PRId32 ".",
1420 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001421 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1422 goto Failed;
1423 }
1424
1425 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001426 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001427 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1428 goto Failed;
1429 }
1430
Jeff Brownffb49772014-10-10 19:01:34 -07001431 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001432 reason = checkWindowReadyForMoreInputLocked(currentTime, focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001433 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001434 injectionResult =
1435 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1436 focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001437 goto Unresponsive;
1438 }
1439
1440 // Success! Output targets.
1441 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001442 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001443 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1444 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001445
1446 // Done.
1447Failed:
1448Unresponsive:
1449 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001450 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001451 if (DEBUG_FOCUS) {
1452 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1453 "timeSpentWaitingForApplication=%0.1fms",
1454 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1455 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001456 return injectionResult;
1457}
1458
1459int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001460 const MotionEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001461 std::vector<InputTarget>& inputTargets,
1462 nsecs_t* nextWakeupTime,
1463 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001464 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001465 enum InjectionPermission {
1466 INJECTION_PERMISSION_UNKNOWN,
1467 INJECTION_PERMISSION_GRANTED,
1468 INJECTION_PERMISSION_DENIED
1469 };
1470
Michael Wrightd02c5b62014-02-10 15:10:22 -08001471 // For security reasons, we defer updating the touch state until we are sure that
1472 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001473 int32_t displayId = entry.displayId;
1474 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001475 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1476
1477 // Update the touch state as needed based on the properties of the touch event.
1478 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1479 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1480 sp<InputWindowHandle> newHoverWindowHandle;
1481
Jeff Brownf086ddb2014-02-11 14:28:48 -08001482 // Copy current touch state into mTempTouchState.
1483 // This state is always reset at the end of this function, so if we don't find state
1484 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001485 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001486 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1487 if (oldStateIndex >= 0) {
1488 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1489 mTempTouchState.copyFrom(*oldState);
1490 }
1491
1492 bool isSplit = mTempTouchState.split;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001493 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0 &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001494 (mTempTouchState.deviceId != entry.deviceId || mTempTouchState.source != entry.source ||
1495 mTempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001496 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1497 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1498 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1499 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1500 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001501 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001502 bool wrongDevice = false;
1503 if (newGesture) {
1504 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001505 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001506 if (DEBUG_FOCUS) {
1507 ALOGD("Dropping event because a pointer for a different device is already down "
1508 "in display %" PRId32,
1509 displayId);
1510 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001511 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001512 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1513 switchedDevice = false;
1514 wrongDevice = true;
1515 goto Failed;
1516 }
1517 mTempTouchState.reset();
1518 mTempTouchState.down = down;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001519 mTempTouchState.deviceId = entry.deviceId;
1520 mTempTouchState.source = entry.source;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001521 mTempTouchState.displayId = displayId;
1522 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001523 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001524 if (DEBUG_FOCUS) {
1525 ALOGI("Dropping move event because a pointer for a different device is already active "
1526 "in display %" PRId32,
1527 displayId);
1528 }
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001529 // TODO: test multiple simultaneous input streams.
1530 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1531 switchedDevice = false;
1532 wrongDevice = true;
1533 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001534 }
1535
1536 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1537 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1538
Garfield Tan00f511d2019-06-12 16:55:40 -07001539 int32_t x;
1540 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001541 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001542 // Always dispatch mouse events to cursor position.
1543 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001544 x = int32_t(entry.xCursorPosition);
1545 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001546 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001547 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1548 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001549 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001550 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001551 sp<InputWindowHandle> newTouchedWindowHandle =
1552 findTouchedWindowAtLocked(displayId, x, y, isDown /*addOutsideTargets*/,
1553 true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001554
1555 std::vector<TouchedMonitor> newGestureMonitors = isDown
1556 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1557 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001558
Michael Wrightd02c5b62014-02-10 15:10:22 -08001559 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001560 if (newTouchedWindowHandle != nullptr &&
1561 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001562 // New window supports splitting, but we should never split mouse events.
1563 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001564 } else if (isSplit) {
1565 // New window does not support splitting but we have already split events.
1566 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001567 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001568 }
1569
1570 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001571 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001572 // Try to assign the pointer to the first foreground window we find, if there is one.
1573 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001574 }
1575
1576 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1577 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001578 "(%d, %d) in display %" PRId32 ".",
1579 x, y, displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00001580 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1581 goto Failed;
1582 }
1583
1584 if (newTouchedWindowHandle != nullptr) {
1585 // Set target flags.
1586 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1587 if (isSplit) {
1588 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001589 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001590 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1591 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1592 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1593 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1594 }
1595
1596 // Update hover state.
1597 if (isHoverAction) {
1598 newHoverWindowHandle = newTouchedWindowHandle;
1599 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1600 newHoverWindowHandle = mLastHoverWindowHandle;
1601 }
1602
1603 // Update the temporary touch state.
1604 BitSet32 pointerIds;
1605 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001606 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001607 pointerIds.markBit(pointerId);
1608 }
1609 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001610 }
1611
Michael Wright3dd60e22019-03-27 22:06:44 +00001612 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001613 } else {
1614 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1615
1616 // If the pointer is not currently down, then ignore the event.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001617 if (!mTempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001618 if (DEBUG_FOCUS) {
1619 ALOGD("Dropping event because the pointer is not down or we previously "
1620 "dropped the pointer down event in display %" PRId32,
1621 displayId);
1622 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001623 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1624 goto Failed;
1625 }
1626
1627 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001628 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001629 mTempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001630 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1631 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001632
1633 sp<InputWindowHandle> oldTouchedWindowHandle =
1634 mTempTouchState.getFirstForegroundWindowHandle();
1635 sp<InputWindowHandle> newTouchedWindowHandle =
1636 findTouchedWindowAtLocked(displayId, x, y);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001637 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1638 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001639 if (DEBUG_FOCUS) {
1640 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1641 oldTouchedWindowHandle->getName().c_str(),
1642 newTouchedWindowHandle->getName().c_str(), displayId);
1643 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001644 // Make a slippery exit from the old window.
1645 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001646 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1647 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001648
1649 // Make a slippery entrance into the new window.
1650 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1651 isSplit = true;
1652 }
1653
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001654 int32_t targetFlags =
1655 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001656 if (isSplit) {
1657 targetFlags |= InputTarget::FLAG_SPLIT;
1658 }
1659 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1660 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1661 }
1662
1663 BitSet32 pointerIds;
1664 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001665 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001666 }
1667 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1668 }
1669 }
1670 }
1671
1672 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1673 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001674 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001675#if DEBUG_HOVER
1676 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001677 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001678#endif
1679 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001680 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT,
1681 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001682 }
1683
1684 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001685 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001686#if DEBUG_HOVER
1687 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001688 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001689#endif
1690 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001691 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1692 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001693 }
1694 }
1695
1696 // Check permission to inject into all touched foreground windows and ensure there
1697 // is at least one touched foreground window.
1698 {
1699 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001700 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001701 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1702 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001703 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001704 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1705 injectionPermission = INJECTION_PERMISSION_DENIED;
1706 goto Failed;
1707 }
1708 }
1709 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001710 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1711 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001712 if (DEBUG_FOCUS) {
1713 ALOGD("Dropping event because there is no touched foreground window in display "
1714 "%" PRId32 " or gesture monitor to receive it.",
1715 displayId);
1716 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001717 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1718 goto Failed;
1719 }
1720
1721 // Permission granted to injection into all touched foreground windows.
1722 injectionPermission = INJECTION_PERMISSION_GRANTED;
1723 }
1724
1725 // Check whether windows listening for outside touches are owned by the same UID. If it is
1726 // set the policy flag that we will not reveal coordinate information to this window.
1727 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1728 sp<InputWindowHandle> foregroundWindowHandle =
1729 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001730 if (foregroundWindowHandle) {
1731 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1732 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1733 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1734 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1735 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1736 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001737 InputTarget::FLAG_ZERO_COORDS,
1738 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001739 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001740 }
1741 }
1742 }
1743 }
1744
1745 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001746 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001747 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001748 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001749 std::string reason =
1750 checkWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle,
1751 entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001752 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001753 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, nullptr,
1754 touchedWindow.windowHandle,
1755 nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001756 goto Unresponsive;
1757 }
1758 }
1759 }
1760
1761 // If this is the first pointer going down and the touched window has a wallpaper
1762 // then also add the touched wallpaper windows so they are locked in for the duration
1763 // of the touch gesture.
1764 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1765 // engine only supports touch events. We would need to add a mechanism similar
1766 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1767 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1768 sp<InputWindowHandle> foregroundWindowHandle =
1769 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001770 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001771 const std::vector<sp<InputWindowHandle>> windowHandles =
1772 getWindowHandlesLocked(displayId);
1773 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001774 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001775 if (info->displayId == displayId &&
1776 windowHandle->getInfo()->layoutParamsType == InputWindowInfo::TYPE_WALLPAPER) {
1777 mTempTouchState
1778 .addOrUpdateWindow(windowHandle,
1779 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1780 InputTarget::
1781 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1782 InputTarget::FLAG_DISPATCH_AS_IS,
1783 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001784 }
1785 }
1786 }
1787 }
1788
1789 // Success! Output targets.
1790 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1791
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001792 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001793 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001794 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001795 }
1796
Michael Wright3dd60e22019-03-27 22:06:44 +00001797 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1798 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001799 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00001800 }
1801
Michael Wrightd02c5b62014-02-10 15:10:22 -08001802 // Drop the outside or hover touch windows since we will not care about them
1803 // in the next iteration.
1804 mTempTouchState.filterNonAsIsTouchWindows();
1805
1806Failed:
1807 // Check injection permission once and for all.
1808 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001809 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001810 injectionPermission = INJECTION_PERMISSION_GRANTED;
1811 } else {
1812 injectionPermission = INJECTION_PERMISSION_DENIED;
1813 }
1814 }
1815
1816 // Update final pieces of touch state if the injector had permission.
1817 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1818 if (!wrongDevice) {
1819 if (switchedDevice) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001820 if (DEBUG_FOCUS) {
1821 ALOGD("Conflicting pointer actions: Switched to a different device.");
1822 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001823 *outConflictingPointerActions = true;
1824 }
1825
1826 if (isHoverAction) {
1827 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001828 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001829 if (DEBUG_FOCUS) {
1830 ALOGD("Conflicting pointer actions: Hover received while pointer was "
1831 "down.");
1832 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001833 *outConflictingPointerActions = true;
1834 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001835 mTempTouchState.reset();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001836 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1837 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001838 mTempTouchState.deviceId = entry.deviceId;
1839 mTempTouchState.source = entry.source;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001840 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001841 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001842 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
1843 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001844 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001845 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001846 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1847 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001848 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001849 if (DEBUG_FOCUS) {
1850 ALOGD("Conflicting pointer actions: Down received while already down.");
1851 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001852 *outConflictingPointerActions = true;
1853 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001854 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1855 // One pointer went up.
1856 if (isSplit) {
1857 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001858 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001859
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001860 for (size_t i = 0; i < mTempTouchState.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001861 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001862 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1863 touchedWindow.pointerIds.clearBit(pointerId);
1864 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001865 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001866 continue;
1867 }
1868 }
1869 i += 1;
1870 }
1871 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001872 }
1873
1874 // Save changes unless the action was scroll in which case the temporary touch
1875 // state was only valid for this one action.
1876 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1877 if (mTempTouchState.displayId >= 0) {
1878 if (oldStateIndex >= 0) {
1879 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1880 } else {
1881 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1882 }
1883 } else if (oldStateIndex >= 0) {
1884 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1885 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001886 }
1887
1888 // Update hover state.
1889 mLastHoverWindowHandle = newHoverWindowHandle;
1890 }
1891 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001892 if (DEBUG_FOCUS) {
1893 ALOGD("Not updating touch focus because injection was denied.");
1894 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001895 }
1896
1897Unresponsive:
1898 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1899 mTempTouchState.reset();
1900
1901 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001902 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001903 if (DEBUG_FOCUS) {
1904 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1905 "timeSpentWaitingForApplication=%0.1fms",
1906 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1907 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001908 return injectionResult;
1909}
1910
1911void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001912 int32_t targetFlags, BitSet32 pointerIds,
1913 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001914 std::vector<InputTarget>::iterator it =
1915 std::find_if(inputTargets.begin(), inputTargets.end(),
1916 [&windowHandle](const InputTarget& inputTarget) {
1917 return inputTarget.inputChannel->getConnectionToken() ==
1918 windowHandle->getToken();
1919 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00001920
Chavi Weingarten114b77f2020-01-15 22:35:10 +00001921 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001922
1923 if (it == inputTargets.end()) {
1924 InputTarget inputTarget;
1925 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1926 if (inputChannel == nullptr) {
1927 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1928 return;
1929 }
1930 inputTarget.inputChannel = inputChannel;
1931 inputTarget.flags = targetFlags;
1932 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
1933 inputTargets.push_back(inputTarget);
1934 it = inputTargets.end() - 1;
1935 }
1936
1937 ALOG_ASSERT(it->flags == targetFlags);
1938 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
1939
1940 it->addPointers(pointerIds, -windowInfo->frameLeft, -windowInfo->frameTop,
1941 windowInfo->windowXScale, windowInfo->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001942}
1943
Michael Wright3dd60e22019-03-27 22:06:44 +00001944void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001945 int32_t displayId, float xOffset,
1946 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001947 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1948 mGlobalMonitorsByDisplay.find(displayId);
1949
1950 if (it != mGlobalMonitorsByDisplay.end()) {
1951 const std::vector<Monitor>& monitors = it->second;
1952 for (const Monitor& monitor : monitors) {
1953 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001954 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001955 }
1956}
1957
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001958void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
1959 float yOffset,
1960 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001961 InputTarget target;
1962 target.inputChannel = monitor.inputChannel;
1963 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Chavi Weingarten65f98b82020-01-16 18:56:50 +00001964 target.setDefaultPointerInfo(xOffset, yOffset, 1 /* windowXScale */, 1 /* windowYScale */);
Michael Wright3dd60e22019-03-27 22:06:44 +00001965 inputTargets.push_back(target);
1966}
1967
Michael Wrightd02c5b62014-02-10 15:10:22 -08001968bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001969 const InjectionState* injectionState) {
1970 if (injectionState &&
1971 (windowHandle == nullptr ||
1972 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
1973 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001974 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001975 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001976 "owned by uid %d",
1977 injectionState->injectorPid, injectionState->injectorUid,
1978 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001979 } else {
1980 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001981 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001982 }
1983 return false;
1984 }
1985 return true;
1986}
1987
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001988bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
1989 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001990 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001991 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1992 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001993 if (otherHandle == windowHandle) {
1994 break;
1995 }
1996
1997 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001998 if (otherInfo->displayId == displayId && otherInfo->visible &&
1999 !otherInfo->isTrustedOverlay() && otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002000 return true;
2001 }
2002 }
2003 return false;
2004}
2005
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002006bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2007 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002008 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002009 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002010 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002011 if (otherHandle == windowHandle) {
2012 break;
2013 }
2014
2015 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002016 if (otherInfo->displayId == displayId && otherInfo->visible &&
2017 !otherInfo->isTrustedOverlay() && otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002018 return true;
2019 }
2020 }
2021 return false;
2022}
2023
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002024std::string InputDispatcher::checkWindowReadyForMoreInputLocked(
2025 nsecs_t currentTime, const sp<InputWindowHandle>& windowHandle,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002026 const EventEntry& eventEntry, const char* targetType) {
Jeff Brownffb49772014-10-10 19:01:34 -07002027 // If the window is paused then keep waiting.
2028 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002029 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07002030 }
2031
2032 // If the window's connection is not registered then keep waiting.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07002033 sp<Connection> connection = getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002034 if (connection == nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002035 return StringPrintf("Waiting because the %s window's input channel is not "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002036 "registered with the input dispatcher. The window may be in the "
2037 "process of being removed.",
2038 targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07002039 }
2040
2041 // If the connection is dead then keep waiting.
Jeff Brownffb49772014-10-10 19:01:34 -07002042 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002043 return StringPrintf("Waiting because the %s window's input connection is %s."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002044 "The window may be in the process of being removed.",
2045 targetType, connection->getStatusLabel());
Jeff Brownffb49772014-10-10 19:01:34 -07002046 }
2047
2048 // If the connection is backed up then keep waiting.
2049 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002050 return StringPrintf("Waiting because the %s window's input channel is full. "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002051 "Outbound queue length: %zu. Wait queue length: %zu.",
2052 targetType, connection->outboundQueue.size(),
2053 connection->waitQueue.size());
Jeff Brownffb49772014-10-10 19:01:34 -07002054 }
2055
2056 // Ensure that the dispatch queues aren't too far backed up for this event.
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002057 if (eventEntry.type == EventEntry::Type::KEY) {
Jeff Brownffb49772014-10-10 19:01:34 -07002058 // If the event is a key event, then we must wait for all previous events to
2059 // complete before delivering it because previous events may have the
2060 // side-effect of transferring focus to a different window and we want to
2061 // ensure that the following keys are sent to the new window.
2062 //
2063 // Suppose the user touches a button in a window then immediately presses "A".
2064 // If the button causes a pop-up window to appear then we want to ensure that
2065 // the "A" key is delivered to the new pop-up window. This is because users
2066 // often anticipate pending UI changes when typing on a keyboard.
2067 // To obtain this behavior, we must serialize key events with respect to all
2068 // prior input events.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002069 if (!connection->outboundQueue.empty() || !connection->waitQueue.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002070 return StringPrintf("Waiting to send key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002071 "finished processing all of the input events that were previously "
2072 "delivered to it. Outbound queue length: %zu. Wait queue length: "
2073 "%zu.",
2074 targetType, connection->outboundQueue.size(),
2075 connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002076 }
Jeff Brownffb49772014-10-10 19:01:34 -07002077 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002078 // Touch events can always be sent to a window immediately because the user intended
2079 // to touch whatever was visible at the time. Even if focus changes or a new
2080 // window appears moments later, the touch event was meant to be delivered to
2081 // whatever window happened to be on screen at the time.
2082 //
2083 // Generic motion events, such as trackball or joystick events are a little trickier.
2084 // Like key events, generic motion events are delivered to the focused window.
2085 // Unlike key events, generic motion events don't tend to transfer focus to other
2086 // windows and it is not important for them to be serialized. So we prefer to deliver
2087 // generic motion events as soon as possible to improve efficiency and reduce lag
2088 // through batching.
2089 //
2090 // The one case where we pause input event delivery is when the wait queue is piling
2091 // up with lots of events because the application is not responding.
2092 // This condition ensures that ANRs are detected reliably.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002093 if (!connection->waitQueue.empty() &&
2094 currentTime >=
2095 connection->waitQueue.front()->deliveryTime + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002096 return StringPrintf("Waiting to send non-key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002097 "finished processing certain input events that were delivered to "
2098 "it over "
2099 "%0.1fms ago. Wait queue length: %zu. Wait queue head age: "
2100 "%0.1fms.",
2101 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
2102 connection->waitQueue.size(),
2103 (currentTime - connection->waitQueue.front()->deliveryTime) *
2104 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002105 }
2106 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002107 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002108}
2109
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002110std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002111 const sp<InputApplicationHandle>& applicationHandle,
2112 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002113 if (applicationHandle != nullptr) {
2114 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002115 std::string label(applicationHandle->getName());
2116 label += " - ";
2117 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002118 return label;
2119 } else {
2120 return applicationHandle->getName();
2121 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002122 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002123 return windowHandle->getName();
2124 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002125 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002126 }
2127}
2128
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002129void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002130 if (eventEntry.type == EventEntry::Type::FOCUS) {
2131 // Focus events are passed to apps, but do not represent user activity.
2132 return;
2133 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002134 int32_t displayId = getTargetDisplayId(eventEntry);
2135 sp<InputWindowHandle> focusedWindowHandle =
2136 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
2137 if (focusedWindowHandle != nullptr) {
2138 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002139 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
2140#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002141 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002142#endif
2143 return;
2144 }
2145 }
2146
2147 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002148 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002149 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002150 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2151 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002152 return;
2153 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002154
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002155 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002156 eventType = USER_ACTIVITY_EVENT_TOUCH;
2157 }
2158 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002159 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002160 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002161 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2162 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002163 return;
2164 }
2165 eventType = USER_ACTIVITY_EVENT_BUTTON;
2166 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002167 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002168 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002169 case EventEntry::Type::CONFIGURATION_CHANGED:
2170 case EventEntry::Type::DEVICE_RESET: {
2171 LOG_ALWAYS_FATAL("%s events are not user activity",
2172 EventEntry::typeToString(eventEntry.type));
2173 break;
2174 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002175 }
2176
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002177 std::unique_ptr<CommandEntry> commandEntry =
2178 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002179 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002180 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002181 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002182}
2183
2184void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002185 const sp<Connection>& connection,
2186 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002187 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002188 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002189 std::string message =
2190 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2191 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002192 ATRACE_NAME(message.c_str());
2193 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002194#if DEBUG_DISPATCH_CYCLE
2195 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002196 "globalScaleFactor=%f, pointerIds=0x%x %s",
2197 connection->getInputChannelName().c_str(), inputTarget.flags,
2198 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2199 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002200#endif
2201
2202 // Skip this event if the connection status is not normal.
2203 // We don't want to enqueue additional outbound events if the connection is broken.
2204 if (connection->status != Connection::STATUS_NORMAL) {
2205#if DEBUG_DISPATCH_CYCLE
2206 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002207 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002208#endif
2209 return;
2210 }
2211
2212 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002213 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2214 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2215 "Entry type %s should not have FLAG_SPLIT",
2216 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002217
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002218 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002219 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002220 MotionEntry* splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002221 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002222 if (!splitMotionEntry) {
2223 return; // split event was dropped
2224 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002225 if (DEBUG_FOCUS) {
2226 ALOGD("channel '%s' ~ Split motion event.",
2227 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002228 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002229 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002230 enqueueDispatchEntriesLocked(currentTime, connection, splitMotionEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002231 splitMotionEntry->release();
2232 return;
2233 }
2234 }
2235
2236 // Not splitting. Enqueue dispatch entries for the event as is.
2237 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2238}
2239
2240void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002241 const sp<Connection>& connection,
2242 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002243 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002244 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002245 std::string message =
2246 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32
2247 ")",
2248 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002249 ATRACE_NAME(message.c_str());
2250 }
2251
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002252 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002253
2254 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002255 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002256 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002257 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002258 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002259 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002260 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002261 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002262 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002263 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002264 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002265 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002266 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002267
2268 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002269 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002270 startDispatchCycleLocked(currentTime, connection);
2271 }
2272}
2273
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002274void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
2275 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002276 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002277 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002278 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002279 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2280 connection->getInputChannelName().c_str(),
2281 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002282 ATRACE_NAME(message.c_str());
2283 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002284 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002285 if (!(inputTargetFlags & dispatchMode)) {
2286 return;
2287 }
2288 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2289
2290 // This is a new event.
2291 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002292 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002293 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002294
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002295 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2296 // different EventEntry than what was passed in.
2297 EventEntry* newEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002298 // Apply target flags and update the connection's input state.
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002299 switch (newEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002300 case EventEntry::Type::KEY: {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002301 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*newEntry);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002302 dispatchEntry->resolvedAction = keyEntry.action;
2303 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002304
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002305 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2306 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002307#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002308 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2309 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002310#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002311 return; // skip the inconsistent event
2312 }
2313 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002314 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002315
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002316 case EventEntry::Type::MOTION: {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002317 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*newEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002318 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2319 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2320 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2321 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2322 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2323 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2324 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2325 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2326 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2327 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2328 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002329 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002330 }
2331 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002332 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2333 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002334#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002335 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2336 "event",
2337 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002338#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002339 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2340 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002341
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002342 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002343 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2344 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2345 }
2346 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2347 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2348 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002349
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002350 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2351 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002352#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002353 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2354 "event",
2355 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002356#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002357 return; // skip the inconsistent event
2358 }
2359
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002360 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002361 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002362
2363 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002364 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002365 case EventEntry::Type::FOCUS: {
2366 break;
2367 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002368 case EventEntry::Type::CONFIGURATION_CHANGED:
2369 case EventEntry::Type::DEVICE_RESET: {
2370 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002371 EventEntry::typeToString(newEntry->type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002372 break;
2373 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002374 }
2375
2376 // Remember that we are waiting for this dispatch to complete.
2377 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002378 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002379 }
2380
2381 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002382 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002383 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002384}
2385
chaviwfd6d3512019-03-25 13:23:49 -07002386void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002387 const sp<IBinder>& newToken) {
chaviw8c9cf542019-03-25 13:02:48 -07002388 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002389 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2390 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002391 return;
2392 }
2393
2394 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2395 if (inputWindowHandle == nullptr) {
2396 return;
2397 }
2398
chaviw8c9cf542019-03-25 13:02:48 -07002399 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002400 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002401
2402 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2403
2404 if (!hasFocusChanged) {
2405 return;
2406 }
2407
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002408 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2409 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002410 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002411 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002412}
2413
2414void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002415 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002416 if (ATRACE_ENABLED()) {
2417 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002418 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002419 ATRACE_NAME(message.c_str());
2420 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002421#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002422 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002423#endif
2424
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002425 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2426 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002427 dispatchEntry->deliveryTime = currentTime;
2428
2429 // Publish the event.
2430 status_t status;
2431 EventEntry* eventEntry = dispatchEntry->eventEntry;
2432 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002433 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002434 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002435
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002436 // Publish the key event.
2437 status = connection->inputPublisher
2438 .publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId,
2439 keyEntry->source, keyEntry->displayId,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06002440 INVALID_HMAC, dispatchEntry->resolvedAction,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002441 dispatchEntry->resolvedFlags, keyEntry->keyCode,
2442 keyEntry->scanCode, keyEntry->metaState,
2443 keyEntry->repeatCount, keyEntry->downTime,
2444 keyEntry->eventTime);
2445 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002446 }
2447
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002448 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002449 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002450
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002451 PointerCoords scaledCoords[MAX_POINTERS];
2452 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2453
chaviw82357092020-01-28 13:13:06 -08002454 // Set the X and Y offset and X and Y scale depending on the input source.
2455 float xOffset = 0.0f, yOffset = 0.0f;
2456 float xScale = 1.0f, yScale = 1.0f;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002457 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
2458 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2459 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002460 xScale = dispatchEntry->windowXScale;
2461 yScale = dispatchEntry->windowYScale;
2462 xOffset = dispatchEntry->xOffset * xScale;
2463 yOffset = dispatchEntry->yOffset * yScale;
2464 if (globalScaleFactor != 1.0f) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002465 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2466 scaledCoords[i] = motionEntry->pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002467 // Don't apply window scale here since we don't want scale to affect raw
2468 // coordinates. The scale will be sent back to the client and applied
2469 // later when requesting relative coordinates.
2470 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2471 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002472 }
2473 usingCoords = scaledCoords;
2474 }
2475 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002476 // We don't want the dispatch target to know.
2477 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
2478 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2479 scaledCoords[i].clear();
2480 }
2481 usingCoords = scaledCoords;
2482 }
2483 }
2484
2485 // Publish the motion event.
2486 status = connection->inputPublisher
2487 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2488 motionEntry->source, motionEntry->displayId,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06002489 INVALID_HMAC, dispatchEntry->resolvedAction,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002490 motionEntry->actionButton,
2491 dispatchEntry->resolvedFlags,
2492 motionEntry->edgeFlags, motionEntry->metaState,
2493 motionEntry->buttonState,
chaviw82357092020-01-28 13:13:06 -08002494 motionEntry->classification, xScale, yScale,
2495 xOffset, yOffset, motionEntry->xPrecision,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002496 motionEntry->yPrecision,
2497 motionEntry->xCursorPosition,
2498 motionEntry->yCursorPosition,
2499 motionEntry->downTime, motionEntry->eventTime,
2500 motionEntry->pointerCount,
2501 motionEntry->pointerProperties, usingCoords);
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05002502 reportTouchEventForStatistics(*motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002503 break;
2504 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002505 case EventEntry::Type::FOCUS: {
2506 FocusEntry* focusEntry = static_cast<FocusEntry*>(eventEntry);
2507 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
2508 focusEntry->hasFocus,
2509 mInTouchMode);
2510 break;
2511 }
2512
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002513 case EventEntry::Type::CONFIGURATION_CHANGED:
2514 case EventEntry::Type::DEVICE_RESET: {
2515 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
2516 EventEntry::typeToString(eventEntry->type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002517 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002518 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002519 }
2520
2521 // Check the result.
2522 if (status) {
2523 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002524 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002525 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002526 "This is unexpected because the wait queue is empty, so the pipe "
2527 "should be empty and we shouldn't have any problems writing an "
2528 "event to it, status=%d",
2529 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002530 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2531 } else {
2532 // Pipe is full and we are waiting for the app to finish process some events
2533 // before sending more events to it.
2534#if DEBUG_DISPATCH_CYCLE
2535 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002536 "waiting for the application to catch up",
2537 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002538#endif
2539 connection->inputPublisherBlocked = true;
2540 }
2541 } else {
2542 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002543 "status=%d",
2544 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002545 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2546 }
2547 return;
2548 }
2549
2550 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002551 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2552 connection->outboundQueue.end(),
2553 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002554 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002555 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002556 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002557 }
2558}
2559
2560void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002561 const sp<Connection>& connection, uint32_t seq,
2562 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002563#if DEBUG_DISPATCH_CYCLE
2564 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002565 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002566#endif
2567
2568 connection->inputPublisherBlocked = false;
2569
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002570 if (connection->status == Connection::STATUS_BROKEN ||
2571 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002572 return;
2573 }
2574
2575 // Notify other system components and prepare to start the next dispatch cycle.
2576 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2577}
2578
2579void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002580 const sp<Connection>& connection,
2581 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002582#if DEBUG_DISPATCH_CYCLE
2583 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002584 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002585#endif
2586
2587 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002588 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002589 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002590 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002591 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002592
2593 // The connection appears to be unrecoverably broken.
2594 // Ignore already broken or zombie connections.
2595 if (connection->status == Connection::STATUS_NORMAL) {
2596 connection->status = Connection::STATUS_BROKEN;
2597
2598 if (notify) {
2599 // Notify other system components.
2600 onDispatchCycleBrokenLocked(currentTime, connection);
2601 }
2602 }
2603}
2604
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002605void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2606 while (!queue.empty()) {
2607 DispatchEntry* dispatchEntry = queue.front();
2608 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002609 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002610 }
2611}
2612
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002613void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002614 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002615 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002616 }
2617 delete dispatchEntry;
2618}
2619
2620int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2621 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2622
2623 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002624 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002625
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002626 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002627 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002628 "fd=%d, events=0x%x",
2629 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002630 return 0; // remove the callback
2631 }
2632
2633 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002634 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002635 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2636 if (!(events & ALOOPER_EVENT_INPUT)) {
2637 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002638 "events=0x%x",
2639 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002640 return 1;
2641 }
2642
2643 nsecs_t currentTime = now();
2644 bool gotOne = false;
2645 status_t status;
2646 for (;;) {
2647 uint32_t seq;
2648 bool handled;
2649 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2650 if (status) {
2651 break;
2652 }
2653 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2654 gotOne = true;
2655 }
2656 if (gotOne) {
2657 d->runCommandsLockedInterruptible();
2658 if (status == WOULD_BLOCK) {
2659 return 1;
2660 }
2661 }
2662
2663 notify = status != DEAD_OBJECT || !connection->monitor;
2664 if (notify) {
2665 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002666 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002667 }
2668 } else {
2669 // Monitor channels are never explicitly unregistered.
2670 // We do it automatically when the remote endpoint is closed so don't warn
2671 // about them.
2672 notify = !connection->monitor;
2673 if (notify) {
2674 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002675 "events=0x%x",
2676 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002677 }
2678 }
2679
2680 // Unregister the channel.
2681 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2682 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002683 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08002684}
2685
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002686void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002687 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002688 for (const auto& pair : mConnectionsByFd) {
2689 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002690 }
2691}
2692
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002693void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002694 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002695 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2696 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2697}
2698
2699void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2700 const CancelationOptions& options,
2701 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2702 for (const auto& it : monitorsByDisplay) {
2703 const std::vector<Monitor>& monitors = it.second;
2704 for (const Monitor& monitor : monitors) {
2705 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002706 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002707 }
2708}
2709
Michael Wrightd02c5b62014-02-10 15:10:22 -08002710void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2711 const sp<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002712 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002713 if (connection == nullptr) {
2714 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002715 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002716
2717 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002718}
2719
2720void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2721 const sp<Connection>& connection, const CancelationOptions& options) {
2722 if (connection->status == Connection::STATUS_BROKEN) {
2723 return;
2724 }
2725
2726 nsecs_t currentTime = now();
2727
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07002728 std::vector<EventEntry*> cancelationEvents =
2729 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002730
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002731 if (cancelationEvents.empty()) {
2732 return;
2733 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002734#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002735 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
2736 "with reality: %s, mode=%d.",
2737 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
2738 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002739#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08002740
2741 InputTarget target;
2742 sp<InputWindowHandle> windowHandle =
2743 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
2744 if (windowHandle != nullptr) {
2745 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2746 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2747 windowInfo->windowXScale, windowInfo->windowYScale);
2748 target.globalScaleFactor = windowInfo->globalScaleFactor;
2749 }
2750 target.inputChannel = connection->inputChannel;
2751 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2752
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002753 for (size_t i = 0; i < cancelationEvents.size(); i++) {
2754 EventEntry* cancelationEventEntry = cancelationEvents[i];
2755 switch (cancelationEventEntry->type) {
2756 case EventEntry::Type::KEY: {
2757 logOutboundKeyDetails("cancel - ",
2758 static_cast<const KeyEntry&>(*cancelationEventEntry));
2759 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002760 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002761 case EventEntry::Type::MOTION: {
2762 logOutboundMotionDetails("cancel - ",
2763 static_cast<const MotionEntry&>(*cancelationEventEntry));
2764 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002765 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002766 case EventEntry::Type::FOCUS: {
2767 LOG_ALWAYS_FATAL("Canceling focus events is not supported");
2768 break;
2769 }
2770 case EventEntry::Type::CONFIGURATION_CHANGED:
2771 case EventEntry::Type::DEVICE_RESET: {
2772 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2773 EventEntry::typeToString(cancelationEventEntry->type));
2774 break;
2775 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002776 }
2777
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002778 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
2779 target, InputTarget::FLAG_DISPATCH_AS_IS);
2780
2781 cancelationEventEntry->release();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002782 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002783
2784 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002785}
2786
Svet Ganov5d3bc372020-01-26 23:11:07 -08002787void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
2788 const sp<Connection>& connection) {
2789 if (connection->status == Connection::STATUS_BROKEN) {
2790 return;
2791 }
2792
2793 nsecs_t currentTime = now();
2794
2795 std::vector<EventEntry*> downEvents =
2796 connection->inputState.synthesizePointerDownEvents(currentTime);
2797
2798 if (downEvents.empty()) {
2799 return;
2800 }
2801
2802#if DEBUG_OUTBOUND_EVENT_DETAILS
2803 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
2804 connection->getInputChannelName().c_str(), downEvents.size());
2805#endif
2806
2807 InputTarget target;
2808 sp<InputWindowHandle> windowHandle =
2809 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
2810 if (windowHandle != nullptr) {
2811 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2812 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2813 windowInfo->windowXScale, windowInfo->windowYScale);
2814 target.globalScaleFactor = windowInfo->globalScaleFactor;
2815 }
2816 target.inputChannel = connection->inputChannel;
2817 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2818
2819 for (EventEntry* downEventEntry : downEvents) {
2820 switch (downEventEntry->type) {
2821 case EventEntry::Type::MOTION: {
2822 logOutboundMotionDetails("down - ",
2823 static_cast<const MotionEntry&>(*downEventEntry));
2824 break;
2825 }
2826
2827 case EventEntry::Type::KEY:
2828 case EventEntry::Type::FOCUS:
2829 case EventEntry::Type::CONFIGURATION_CHANGED:
2830 case EventEntry::Type::DEVICE_RESET: {
2831 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2832 EventEntry::typeToString(downEventEntry->type));
2833 break;
2834 }
2835 }
2836
2837 enqueueDispatchEntryLocked(connection, downEventEntry, // increments ref
2838 target, InputTarget::FLAG_DISPATCH_AS_IS);
2839
2840 downEventEntry->release();
2841 }
2842
2843 startDispatchCycleLocked(currentTime, connection);
2844}
2845
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002846MotionEntry* InputDispatcher::splitMotionEvent(const MotionEntry& originalMotionEntry,
Garfield Tane84e6f92019-08-29 17:28:41 -07002847 BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002848 ALOG_ASSERT(pointerIds.value != 0);
2849
2850 uint32_t splitPointerIndexMap[MAX_POINTERS];
2851 PointerProperties splitPointerProperties[MAX_POINTERS];
2852 PointerCoords splitPointerCoords[MAX_POINTERS];
2853
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002854 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002855 uint32_t splitPointerCount = 0;
2856
2857 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002858 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002859 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002860 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002861 uint32_t pointerId = uint32_t(pointerProperties.id);
2862 if (pointerIds.hasBit(pointerId)) {
2863 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2864 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2865 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002866 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002867 splitPointerCount += 1;
2868 }
2869 }
2870
2871 if (splitPointerCount != pointerIds.count()) {
2872 // This is bad. We are missing some of the pointers that we expected to deliver.
2873 // Most likely this indicates that we received an ACTION_MOVE events that has
2874 // different pointer ids than we expected based on the previous ACTION_DOWN
2875 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2876 // in this way.
2877 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002878 "we expected there to be %d pointers. This probably means we received "
2879 "a broken sequence of pointer ids from the input device.",
2880 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002881 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002882 }
2883
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002884 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002885 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002886 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
2887 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002888 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2889 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002890 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002891 uint32_t pointerId = uint32_t(pointerProperties.id);
2892 if (pointerIds.hasBit(pointerId)) {
2893 if (pointerIds.count() == 1) {
2894 // The first/last pointer went down/up.
2895 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002896 ? AMOTION_EVENT_ACTION_DOWN
2897 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002898 } else {
2899 // A secondary pointer went down/up.
2900 uint32_t splitPointerIndex = 0;
2901 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2902 splitPointerIndex += 1;
2903 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002904 action = maskedAction |
2905 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002906 }
2907 } else {
2908 // An unrelated pointer changed.
2909 action = AMOTION_EVENT_ACTION_MOVE;
2910 }
2911 }
2912
Garfield Tan00f511d2019-06-12 16:55:40 -07002913 MotionEntry* splitMotionEntry =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002914 new MotionEntry(originalMotionEntry.sequenceNum, originalMotionEntry.eventTime,
2915 originalMotionEntry.deviceId, originalMotionEntry.source,
2916 originalMotionEntry.displayId, originalMotionEntry.policyFlags, action,
2917 originalMotionEntry.actionButton, originalMotionEntry.flags,
2918 originalMotionEntry.metaState, originalMotionEntry.buttonState,
2919 originalMotionEntry.classification, originalMotionEntry.edgeFlags,
2920 originalMotionEntry.xPrecision, originalMotionEntry.yPrecision,
2921 originalMotionEntry.xCursorPosition,
2922 originalMotionEntry.yCursorPosition, originalMotionEntry.downTime,
Garfield Tan00f511d2019-06-12 16:55:40 -07002923 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002925 if (originalMotionEntry.injectionState) {
2926 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002927 splitMotionEntry->injectionState->refCount += 1;
2928 }
2929
2930 return splitMotionEntry;
2931}
2932
2933void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2934#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002935 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002936#endif
2937
2938 bool needWake;
2939 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002940 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002941
Prabir Pradhan42611e02018-11-27 14:04:02 -08002942 ConfigurationChangedEntry* newEntry =
2943 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002944 needWake = enqueueInboundEventLocked(newEntry);
2945 } // release lock
2946
2947 if (needWake) {
2948 mLooper->wake();
2949 }
2950}
2951
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002952/**
2953 * If one of the meta shortcuts is detected, process them here:
2954 * Meta + Backspace -> generate BACK
2955 * Meta + Enter -> generate HOME
2956 * This will potentially overwrite keyCode and metaState.
2957 */
2958void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002959 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002960 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2961 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2962 if (keyCode == AKEYCODE_DEL) {
2963 newKeyCode = AKEYCODE_BACK;
2964 } else if (keyCode == AKEYCODE_ENTER) {
2965 newKeyCode = AKEYCODE_HOME;
2966 }
2967 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002968 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002969 struct KeyReplacement replacement = {keyCode, deviceId};
2970 mReplacedKeys.add(replacement, newKeyCode);
2971 keyCode = newKeyCode;
2972 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2973 }
2974 } else if (action == AKEY_EVENT_ACTION_UP) {
2975 // In order to maintain a consistent stream of up and down events, check to see if the key
2976 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2977 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002978 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002979 struct KeyReplacement replacement = {keyCode, deviceId};
2980 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2981 if (index >= 0) {
2982 keyCode = mReplacedKeys.valueAt(index);
2983 mReplacedKeys.removeItemsAt(index);
2984 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2985 }
2986 }
2987}
2988
Michael Wrightd02c5b62014-02-10 15:10:22 -08002989void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2990#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002991 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
2992 "policyFlags=0x%x, action=0x%x, "
2993 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
2994 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2995 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
2996 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002997#endif
2998 if (!validateKeyEvent(args->action)) {
2999 return;
3000 }
3001
3002 uint32_t policyFlags = args->policyFlags;
3003 int32_t flags = args->flags;
3004 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003005 // InputDispatcher tracks and generates key repeats on behalf of
3006 // whatever notifies it, so repeatCount should always be set to 0
3007 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003008 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3009 policyFlags |= POLICY_FLAG_VIRTUAL;
3010 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3011 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003012 if (policyFlags & POLICY_FLAG_FUNCTION) {
3013 metaState |= AMETA_FUNCTION_ON;
3014 }
3015
3016 policyFlags |= POLICY_FLAG_TRUSTED;
3017
Michael Wright78f24442014-08-06 15:55:28 -07003018 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003019 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003020
Michael Wrightd02c5b62014-02-10 15:10:22 -08003021 KeyEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06003022 event.initialize(args->deviceId, args->source, args->displayId, INVALID_HMAC, args->action,
3023 flags, keyCode, args->scanCode, metaState, repeatCount, args->downTime,
3024 args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003025
Michael Wright2b3c3302018-03-02 17:19:13 +00003026 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003027 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003028 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3029 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003030 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003031 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003032
Michael Wrightd02c5b62014-02-10 15:10:22 -08003033 bool needWake;
3034 { // acquire lock
3035 mLock.lock();
3036
3037 if (shouldSendKeyToInputFilterLocked(args)) {
3038 mLock.unlock();
3039
3040 policyFlags |= POLICY_FLAG_FILTERED;
3041 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3042 return; // event was consumed by the filter
3043 }
3044
3045 mLock.lock();
3046 }
3047
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003048 KeyEntry* newEntry =
3049 new KeyEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
3050 args->displayId, policyFlags, args->action, flags, keyCode,
3051 args->scanCode, metaState, repeatCount, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003052
3053 needWake = enqueueInboundEventLocked(newEntry);
3054 mLock.unlock();
3055 } // release lock
3056
3057 if (needWake) {
3058 mLooper->wake();
3059 }
3060}
3061
3062bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3063 return mInputFilterEnabled;
3064}
3065
3066void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3067#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08003068 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07003069 ", policyFlags=0x%x, "
3070 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3071 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003072 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07003073 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3074 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
Jaewan Kim372fbe42019-10-02 10:58:46 +09003075 args->edgeFlags, args->xPrecision, args->yPrecision, args->xCursorPosition,
Garfield Tan00f511d2019-06-12 16:55:40 -07003076 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003077 for (uint32_t i = 0; i < args->pointerCount; i++) {
3078 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003079 "x=%f, y=%f, pressure=%f, size=%f, "
3080 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3081 "orientation=%f",
3082 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3083 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3084 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3085 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3086 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3087 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3088 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3089 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3090 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3091 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003092 }
3093#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003094 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3095 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003096 return;
3097 }
3098
3099 uint32_t policyFlags = args->policyFlags;
3100 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003101
3102 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003103 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003104 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3105 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003106 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003107 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003108
3109 bool needWake;
3110 { // acquire lock
3111 mLock.lock();
3112
3113 if (shouldSendMotionToInputFilterLocked(args)) {
3114 mLock.unlock();
3115
3116 MotionEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06003117 event.initialize(args->deviceId, args->source, args->displayId, INVALID_HMAC,
3118 args->action, args->actionButton, args->flags, args->edgeFlags,
3119 args->metaState, args->buttonState, args->classification, 1 /*xScale*/,
3120 1 /*yScale*/, 0 /* xOffset */, 0 /* yOffset */, args->xPrecision,
Garfield Tan00f511d2019-06-12 16:55:40 -07003121 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3122 args->downTime, args->eventTime, args->pointerCount,
3123 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003124
3125 policyFlags |= POLICY_FLAG_FILTERED;
3126 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3127 return; // event was consumed by the filter
3128 }
3129
3130 mLock.lock();
3131 }
3132
3133 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07003134 MotionEntry* newEntry =
3135 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
3136 args->displayId, policyFlags, args->action, args->actionButton,
3137 args->flags, args->metaState, args->buttonState,
3138 args->classification, args->edgeFlags, args->xPrecision,
3139 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3140 args->downTime, args->pointerCount, args->pointerProperties,
3141 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003142
3143 needWake = enqueueInboundEventLocked(newEntry);
3144 mLock.unlock();
3145 } // release lock
3146
3147 if (needWake) {
3148 mLooper->wake();
3149 }
3150}
3151
3152bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003153 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003154}
3155
3156void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3157#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003158 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003159 "switchMask=0x%08x",
3160 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003161#endif
3162
3163 uint32_t policyFlags = args->policyFlags;
3164 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003165 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003166}
3167
3168void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3169#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003170 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3171 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003172#endif
3173
3174 bool needWake;
3175 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003176 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003177
Prabir Pradhan42611e02018-11-27 14:04:02 -08003178 DeviceResetEntry* newEntry =
3179 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003180 needWake = enqueueInboundEventLocked(newEntry);
3181 } // release lock
3182
3183 if (needWake) {
3184 mLooper->wake();
3185 }
3186}
3187
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003188int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid,
3189 int32_t injectorUid, int32_t syncMode,
3190 int32_t timeoutMillis, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003191#if DEBUG_INBOUND_EVENT_DETAILS
3192 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003193 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
3194 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003195#endif
3196
3197 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
3198
3199 policyFlags |= POLICY_FLAG_INJECTED;
3200 if (hasInjectionPermission(injectorPid, injectorUid)) {
3201 policyFlags |= POLICY_FLAG_TRUSTED;
3202 }
3203
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003204 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003205 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003206 case AINPUT_EVENT_TYPE_KEY: {
3207 KeyEvent keyEvent;
3208 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
3209 int32_t action = keyEvent.getAction();
3210 if (!validateKeyEvent(action)) {
3211 return INPUT_EVENT_INJECTION_FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003212 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003213
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003214 int32_t flags = keyEvent.getFlags();
3215 int32_t keyCode = keyEvent.getKeyCode();
3216 int32_t metaState = keyEvent.getMetaState();
3217 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
3218 /*byref*/ keyCode, /*byref*/ metaState);
3219 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(),
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06003220 keyEvent.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003221 keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
3222 keyEvent.getDownTime(), keyEvent.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003223
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003224 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3225 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003226 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003227
3228 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3229 android::base::Timer t;
3230 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3231 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3232 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3233 std::to_string(t.duration().count()).c_str());
3234 }
3235 }
3236
3237 mLock.lock();
3238 KeyEntry* injectedEntry =
3239 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
3240 keyEvent.getDeviceId(), keyEvent.getSource(),
3241 keyEvent.getDisplayId(), policyFlags, action, flags,
3242 keyEvent.getKeyCode(), keyEvent.getScanCode(),
3243 keyEvent.getMetaState(), keyEvent.getRepeatCount(),
3244 keyEvent.getDownTime());
3245 injectedEntries.push(injectedEntry);
3246 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003247 }
3248
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003249 case AINPUT_EVENT_TYPE_MOTION: {
3250 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3251 int32_t action = motionEvent->getAction();
3252 size_t pointerCount = motionEvent->getPointerCount();
3253 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3254 int32_t actionButton = motionEvent->getActionButton();
3255 int32_t displayId = motionEvent->getDisplayId();
3256 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
3257 return INPUT_EVENT_INJECTION_FAILED;
3258 }
3259
3260 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3261 nsecs_t eventTime = motionEvent->getEventTime();
3262 android::base::Timer t;
3263 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3264 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3265 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3266 std::to_string(t.duration().count()).c_str());
3267 }
3268 }
3269
3270 mLock.lock();
3271 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3272 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
3273 MotionEntry* injectedEntry =
Garfield Tan00f511d2019-06-12 16:55:40 -07003274 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3275 motionEvent->getDeviceId(), motionEvent->getSource(),
3276 motionEvent->getDisplayId(), policyFlags, action, actionButton,
3277 motionEvent->getFlags(), motionEvent->getMetaState(),
3278 motionEvent->getButtonState(), motionEvent->getClassification(),
3279 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3280 motionEvent->getYPrecision(),
3281 motionEvent->getRawXCursorPosition(),
3282 motionEvent->getRawYCursorPosition(),
3283 motionEvent->getDownTime(), uint32_t(pointerCount),
3284 pointerProperties, samplePointerCoords,
3285 motionEvent->getXOffset(), motionEvent->getYOffset());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003286 injectedEntries.push(injectedEntry);
3287 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3288 sampleEventTimes += 1;
3289 samplePointerCoords += pointerCount;
3290 MotionEntry* nextInjectedEntry =
3291 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3292 motionEvent->getDeviceId(), motionEvent->getSource(),
3293 motionEvent->getDisplayId(), policyFlags, action,
3294 actionButton, motionEvent->getFlags(),
3295 motionEvent->getMetaState(), motionEvent->getButtonState(),
3296 motionEvent->getClassification(),
3297 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3298 motionEvent->getYPrecision(),
3299 motionEvent->getRawXCursorPosition(),
3300 motionEvent->getRawYCursorPosition(),
3301 motionEvent->getDownTime(), uint32_t(pointerCount),
3302 pointerProperties, samplePointerCoords,
3303 motionEvent->getXOffset(), motionEvent->getYOffset());
3304 injectedEntries.push(nextInjectedEntry);
3305 }
3306 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003307 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003308
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003309 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003310 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003311 return INPUT_EVENT_INJECTION_FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003312 }
3313
3314 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3315 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3316 injectionState->injectionIsAsync = true;
3317 }
3318
3319 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003320 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003321
3322 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003323 while (!injectedEntries.empty()) {
3324 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3325 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003326 }
3327
3328 mLock.unlock();
3329
3330 if (needWake) {
3331 mLooper->wake();
3332 }
3333
3334 int32_t injectionResult;
3335 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003336 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003337
3338 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3339 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3340 } else {
3341 for (;;) {
3342 injectionResult = injectionState->injectionResult;
3343 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3344 break;
3345 }
3346
3347 nsecs_t remainingTimeout = endTime - now();
3348 if (remainingTimeout <= 0) {
3349#if DEBUG_INJECTION
3350 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003351 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003352#endif
3353 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3354 break;
3355 }
3356
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003357 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003358 }
3359
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003360 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED &&
3361 syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003362 while (injectionState->pendingForegroundDispatches != 0) {
3363#if DEBUG_INJECTION
3364 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003365 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003366#endif
3367 nsecs_t remainingTimeout = endTime - now();
3368 if (remainingTimeout <= 0) {
3369#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003370 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3371 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003372#endif
3373 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3374 break;
3375 }
3376
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003377 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003378 }
3379 }
3380 }
3381
3382 injectionState->release();
3383 } // release lock
3384
3385#if DEBUG_INJECTION
3386 ALOGD("injectInputEvent - Finished with result %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003387 "injectorPid=%d, injectorUid=%d",
3388 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003389#endif
3390
3391 return injectionResult;
3392}
3393
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003394std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
3395 return nullptr;
3396}
3397
Michael Wrightd02c5b62014-02-10 15:10:22 -08003398bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003399 return injectorUid == 0 ||
3400 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003401}
3402
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003403void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003404 InjectionState* injectionState = entry->injectionState;
3405 if (injectionState) {
3406#if DEBUG_INJECTION
3407 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003408 "injectorPid=%d, injectorUid=%d",
3409 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003410#endif
3411
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003412 if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003413 // Log the outcome since the injector did not wait for the injection result.
3414 switch (injectionResult) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003415 case INPUT_EVENT_INJECTION_SUCCEEDED:
3416 ALOGV("Asynchronous input event injection succeeded.");
3417 break;
3418 case INPUT_EVENT_INJECTION_FAILED:
3419 ALOGW("Asynchronous input event injection failed.");
3420 break;
3421 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3422 ALOGW("Asynchronous input event injection permission denied.");
3423 break;
3424 case INPUT_EVENT_INJECTION_TIMED_OUT:
3425 ALOGW("Asynchronous input event injection timed out.");
3426 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003427 }
3428 }
3429
3430 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003431 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003432 }
3433}
3434
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003435void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003436 InjectionState* injectionState = entry->injectionState;
3437 if (injectionState) {
3438 injectionState->pendingForegroundDispatches += 1;
3439 }
3440}
3441
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003442void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003443 InjectionState* injectionState = entry->injectionState;
3444 if (injectionState) {
3445 injectionState->pendingForegroundDispatches -= 1;
3446
3447 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003448 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003449 }
3450 }
3451}
3452
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003453std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3454 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003455 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003456}
3457
Michael Wrightd02c5b62014-02-10 15:10:22 -08003458sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003459 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003460 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003461 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3462 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003463 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003464 return windowHandle;
3465 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003466 }
3467 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003468 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003469}
3470
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003471bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003472 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003473 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3474 for (const sp<InputWindowHandle>& handle : windowHandles) {
3475 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003476 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003477 ALOGE("Found window %s in display %" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003478 ", but it should belong to display %" PRId32,
3479 windowHandle->getName().c_str(), it.first,
3480 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003481 }
3482 return true;
3483 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003484 }
3485 }
3486 return false;
3487}
3488
Robert Carr5c8a0262018-10-03 16:30:44 -07003489sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3490 size_t count = mInputChannelsByToken.count(token);
3491 if (count == 0) {
3492 return nullptr;
3493 }
3494 return mInputChannelsByToken.at(token);
3495}
3496
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003497void InputDispatcher::updateWindowHandlesForDisplayLocked(
3498 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3499 if (inputWindowHandles.empty()) {
3500 // Remove all handles on a display if there are no windows left.
3501 mWindowHandlesByDisplay.erase(displayId);
3502 return;
3503 }
3504
3505 // Since we compare the pointer of input window handles across window updates, we need
3506 // to make sure the handle object for the same window stays unchanged across updates.
3507 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003508 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003509 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003510 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003511 }
3512
3513 std::vector<sp<InputWindowHandle>> newHandles;
3514 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3515 if (!handle->updateInfo()) {
3516 // handle no longer valid
3517 continue;
3518 }
3519
3520 const InputWindowInfo* info = handle->getInfo();
3521 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3522 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3523 const bool noInputChannel =
3524 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3525 const bool canReceiveInput =
3526 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3527 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3528 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003529 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003530 handle->getName().c_str());
3531 }
3532 continue;
3533 }
3534
3535 if (info->displayId != displayId) {
3536 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3537 handle->getName().c_str(), displayId, info->displayId);
3538 continue;
3539 }
3540
chaviwaf87b3e2019-10-01 16:59:28 -07003541 if (oldHandlesById.find(handle->getId()) != oldHandlesById.end()) {
3542 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003543 oldHandle->updateFrom(handle);
3544 newHandles.push_back(oldHandle);
3545 } else {
3546 newHandles.push_back(handle);
3547 }
3548 }
3549
3550 // Insert or replace
3551 mWindowHandlesByDisplay[displayId] = newHandles;
3552}
3553
Arthur Hungb92218b2018-08-14 12:00:21 +08003554/**
3555 * Called from InputManagerService, update window handle list by displayId that can receive input.
3556 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3557 * If set an empty list, remove all handles from the specific display.
3558 * For focused handle, check if need to change and send a cancel event to previous one.
3559 * For removed handle, check if need to send a cancel event if already in touch.
3560 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003561void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003562 int32_t displayId,
3563 const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003564 if (DEBUG_FOCUS) {
3565 std::string windowList;
3566 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
3567 windowList += iwh->getName() + " ";
3568 }
3569 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
3570 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003571 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003572 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003573
Arthur Hungb92218b2018-08-14 12:00:21 +08003574 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003575 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3576 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003577
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003578 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3579
Tiger Huang721e26f2018-07-24 22:26:19 +08003580 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003581 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003582 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3583 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3584 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3585 windowHandle->getInfo()->visible) {
3586 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003587 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003588 if (windowHandle == mLastHoverWindowHandle) {
3589 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003590 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003591 }
3592
3593 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003594 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003595 }
3596
Tiger Huang721e26f2018-07-24 22:26:19 +08003597 sp<InputWindowHandle> oldFocusedWindowHandle =
3598 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3599
chaviwaf87b3e2019-10-01 16:59:28 -07003600 if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003601 if (oldFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003602 if (DEBUG_FOCUS) {
3603 ALOGD("Focus left window: %s in display %" PRId32,
3604 oldFocusedWindowHandle->getName().c_str(), displayId);
3605 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003606 sp<InputChannel> focusedInputChannel =
3607 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003608 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003609 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003610 "focus left window");
3611 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003612 enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003613 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003614 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003615 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003616 if (newFocusedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003617 if (DEBUG_FOCUS) {
3618 ALOGD("Focus entered window: %s in display %" PRId32,
3619 newFocusedWindowHandle->getName().c_str(), displayId);
3620 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003621 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003622 enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003623 }
Robert Carrf759f162018-11-13 12:57:11 -08003624
3625 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003626 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003627 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003628 }
3629
Arthur Hungb92218b2018-08-14 12:00:21 +08003630 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3631 if (stateIndex >= 0) {
3632 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003633 for (size_t i = 0; i < state.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003634 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003635 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003636 if (DEBUG_FOCUS) {
3637 ALOGD("Touched window was removed: %s in display %" PRId32,
3638 touchedWindow.windowHandle->getName().c_str(), displayId);
3639 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003640 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003641 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003642 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003643 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003644 "touched window was removed");
3645 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
3646 options);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003647 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003648 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003649 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003650 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003651 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003652 }
3653 }
3654
3655 // Release information for windows that are no longer present.
3656 // This ensures that unused input channels are released promptly.
3657 // Otherwise, they might stick around until the window handle is destroyed
3658 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003659 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003660 if (!hasWindowHandleLocked(oldWindowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003661 if (DEBUG_FOCUS) {
3662 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
3663 }
Arthur Hung3b413f22018-10-26 18:05:34 +08003664 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003665 }
3666 }
3667 } // release lock
3668
3669 // Wake up poll loop since it may need to make new input dispatching choices.
3670 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003671
3672 if (setInputWindowsListener) {
3673 setInputWindowsListener->onSetInputWindowsFinished();
3674 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003675}
3676
3677void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003678 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003679 if (DEBUG_FOCUS) {
3680 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
3681 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
3682 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003683 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003684 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003685
Tiger Huang721e26f2018-07-24 22:26:19 +08003686 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3687 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003688 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003689 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3690 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003691 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003692 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003693 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003694 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003695 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003696 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003697 oldFocusedApplicationHandle.clear();
3698 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003699 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003700 } // release lock
3701
3702 // Wake up poll loop since it may need to make new input dispatching choices.
3703 mLooper->wake();
3704}
3705
Tiger Huang721e26f2018-07-24 22:26:19 +08003706/**
3707 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3708 * the display not specified.
3709 *
3710 * We track any unreleased events for each window. If a window loses the ability to receive the
3711 * released event, we will send a cancel event to it. So when the focused display is changed, we
3712 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3713 * display. The display-specified events won't be affected.
3714 */
3715void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003716 if (DEBUG_FOCUS) {
3717 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3718 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003719 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003720 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003721
3722 if (mFocusedDisplayId != displayId) {
3723 sp<InputWindowHandle> oldFocusedWindowHandle =
3724 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3725 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003726 sp<InputChannel> inputChannel =
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003727 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003728 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003729 CancelationOptions
3730 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3731 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003732 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003733 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3734 }
3735 }
3736 mFocusedDisplayId = displayId;
3737
3738 // Sanity check
3739 sp<InputWindowHandle> newFocusedWindowHandle =
3740 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003741 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003742
Tiger Huang721e26f2018-07-24 22:26:19 +08003743 if (newFocusedWindowHandle == nullptr) {
3744 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3745 if (!mFocusedWindowHandlesByDisplay.empty()) {
3746 ALOGE("But another display has a focused window:");
3747 for (auto& it : mFocusedWindowHandlesByDisplay) {
3748 const int32_t displayId = it.first;
3749 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003750 ALOGE("Display #%" PRId32 " has focused window: '%s'\n", displayId,
3751 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003752 }
3753 }
3754 }
3755 }
3756
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003757 if (DEBUG_FOCUS) {
3758 logDispatchStateLocked();
3759 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003760 } // release lock
3761
3762 // Wake up poll loop since it may need to make new input dispatching choices.
3763 mLooper->wake();
3764}
3765
Michael Wrightd02c5b62014-02-10 15:10:22 -08003766void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003767 if (DEBUG_FOCUS) {
3768 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3769 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003770
3771 bool changed;
3772 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003773 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003774
3775 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3776 if (mDispatchFrozen && !frozen) {
3777 resetANRTimeoutsLocked();
3778 }
3779
3780 if (mDispatchEnabled && !enabled) {
3781 resetAndDropEverythingLocked("dispatcher is being disabled");
3782 }
3783
3784 mDispatchEnabled = enabled;
3785 mDispatchFrozen = frozen;
3786 changed = true;
3787 } else {
3788 changed = false;
3789 }
3790
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003791 if (DEBUG_FOCUS) {
3792 logDispatchStateLocked();
3793 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003794 } // release lock
3795
3796 if (changed) {
3797 // Wake up poll loop since it may need to make new input dispatching choices.
3798 mLooper->wake();
3799 }
3800}
3801
3802void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003803 if (DEBUG_FOCUS) {
3804 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3805 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003806
3807 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003808 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003809
3810 if (mInputFilterEnabled == enabled) {
3811 return;
3812 }
3813
3814 mInputFilterEnabled = enabled;
3815 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3816 } // release lock
3817
3818 // Wake up poll loop since there might be work to do to drop everything.
3819 mLooper->wake();
3820}
3821
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08003822void InputDispatcher::setInTouchMode(bool inTouchMode) {
3823 std::scoped_lock lock(mLock);
3824 mInTouchMode = inTouchMode;
3825}
3826
chaviwfbe5d9c2018-12-26 12:23:37 -08003827bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3828 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003829 if (DEBUG_FOCUS) {
3830 ALOGD("Trivial transfer to same window.");
3831 }
chaviwfbe5d9c2018-12-26 12:23:37 -08003832 return true;
3833 }
3834
Michael Wrightd02c5b62014-02-10 15:10:22 -08003835 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003836 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003837
chaviwfbe5d9c2018-12-26 12:23:37 -08003838 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3839 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003840 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003841 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003842 return false;
3843 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003844 if (DEBUG_FOCUS) {
3845 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3846 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3847 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003849 if (DEBUG_FOCUS) {
3850 ALOGD("Cannot transfer focus because windows are on different displays.");
3851 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003852 return false;
3853 }
3854
3855 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003856 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3857 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3858 for (size_t i = 0; i < state.windows.size(); i++) {
3859 const TouchedWindow& touchedWindow = state.windows[i];
3860 if (touchedWindow.windowHandle == fromWindowHandle) {
3861 int32_t oldTargetFlags = touchedWindow.targetFlags;
3862 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003863
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003864 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003866 int32_t newTargetFlags = oldTargetFlags &
3867 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
3868 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003869 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003870
Jeff Brownf086ddb2014-02-11 14:28:48 -08003871 found = true;
3872 goto Found;
3873 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003874 }
3875 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003876 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003877
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003878 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003879 if (DEBUG_FOCUS) {
3880 ALOGD("Focus transfer failed because from window did not have focus.");
3881 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003882 return false;
3883 }
3884
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07003885 sp<Connection> fromConnection = getConnectionLocked(fromToken);
3886 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003887 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003888 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003889 CancelationOptions
3890 options(CancelationOptions::CANCEL_POINTER_EVENTS,
3891 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003892 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003893 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003894 }
3895
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003896 if (DEBUG_FOCUS) {
3897 logDispatchStateLocked();
3898 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003899 } // release lock
3900
3901 // Wake up poll loop since it may need to make new input dispatching choices.
3902 mLooper->wake();
3903 return true;
3904}
3905
3906void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003907 if (DEBUG_FOCUS) {
3908 ALOGD("Resetting and dropping all events (%s).", reason);
3909 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003910
3911 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3912 synthesizeCancelationEventsForAllConnectionsLocked(options);
3913
3914 resetKeyRepeatLocked();
3915 releasePendingEventLocked();
3916 drainInboundQueueLocked();
3917 resetANRTimeoutsLocked();
3918
Jeff Brownf086ddb2014-02-11 14:28:48 -08003919 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003920 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003921 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003922}
3923
3924void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003925 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003926 dumpDispatchStateLocked(dump);
3927
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003928 std::istringstream stream(dump);
3929 std::string line;
3930
3931 while (std::getline(stream, line, '\n')) {
3932 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003933 }
3934}
3935
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003936void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003937 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3938 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3939 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003940 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003941
Tiger Huang721e26f2018-07-24 22:26:19 +08003942 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3943 dump += StringPrintf(INDENT "FocusedApplications:\n");
3944 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3945 const int32_t displayId = it.first;
3946 const sp<InputApplicationHandle>& applicationHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003947 dump += StringPrintf(INDENT2 "displayId=%" PRId32
3948 ", name='%s', dispatchingTimeout=%0.3fms\n",
3949 displayId, applicationHandle->getName().c_str(),
3950 applicationHandle->getDispatchingTimeout(
3951 DEFAULT_INPUT_DISPATCHING_TIMEOUT) /
3952 1000000.0);
Tiger Huang721e26f2018-07-24 22:26:19 +08003953 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003954 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003955 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003956 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003957
3958 if (!mFocusedWindowHandlesByDisplay.empty()) {
3959 dump += StringPrintf(INDENT "FocusedWindows:\n");
3960 for (auto& it : mFocusedWindowHandlesByDisplay) {
3961 const int32_t displayId = it.first;
3962 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003963 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
3964 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003965 }
3966 } else {
3967 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3968 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003969
Jeff Brownf086ddb2014-02-11 14:28:48 -08003970 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003971 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003972 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3973 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003974 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003975 state.displayId, toString(state.down), toString(state.split),
3976 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003977 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003978 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003979 for (size_t i = 0; i < state.windows.size(); i++) {
3980 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003981 dump += StringPrintf(INDENT4
3982 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3983 i, touchedWindow.windowHandle->getName().c_str(),
3984 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003985 }
3986 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003987 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003988 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003989 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003990 dump += INDENT3 "Portal windows:\n";
3991 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003992 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003993 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
3994 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003995 }
3996 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003997 }
3998 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003999 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004000 }
4001
Arthur Hungb92218b2018-08-14 12:00:21 +08004002 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004003 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004004 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004005 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004006 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004007 dump += INDENT2 "Windows:\n";
4008 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004009 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004010 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004011
Arthur Hungb92218b2018-08-14 12:00:21 +08004012 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004013 "portalToDisplayId=%d, paused=%s, hasFocus=%s, "
chaviwcb923212019-12-30 14:05:11 -08004014 "hasWallpaper=%s, visible=%s, canReceiveKeys=%s, "
4015 "flags=0x%08x, type=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004016 "frame=[%d,%d][%d,%d], globalScale=%f, "
chaviwcb923212019-12-30 14:05:11 -08004017 "windowScale=(%f,%f), touchableRegion=",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004018 i, windowInfo->name.c_str(), windowInfo->displayId,
4019 windowInfo->portalToDisplayId,
4020 toString(windowInfo->paused),
4021 toString(windowInfo->hasFocus),
4022 toString(windowInfo->hasWallpaper),
4023 toString(windowInfo->visible),
4024 toString(windowInfo->canReceiveKeys),
4025 windowInfo->layoutParamsFlags,
chaviwcb923212019-12-30 14:05:11 -08004026 windowInfo->layoutParamsType, windowInfo->frameLeft,
4027 windowInfo->frameTop, windowInfo->frameRight,
4028 windowInfo->frameBottom, windowInfo->globalScaleFactor,
4029 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08004030 dumpRegion(dump, windowInfo->touchableRegion);
4031 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
4032 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004033 windowInfo->ownerPid, windowInfo->ownerUid,
4034 windowInfo->dispatchingTimeout / 1000000.0);
Arthur Hungb92218b2018-08-14 12:00:21 +08004035 }
4036 } else {
4037 dump += INDENT2 "Windows: <none>\n";
4038 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004039 }
4040 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004041 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004042 }
4043
Michael Wright3dd60e22019-03-27 22:06:44 +00004044 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004045 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004046 const std::vector<Monitor>& monitors = it.second;
4047 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4048 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004049 }
4050 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004051 const std::vector<Monitor>& monitors = it.second;
4052 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4053 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004054 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004055 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004056 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004057 }
4058
4059 nsecs_t currentTime = now();
4060
4061 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004062 if (!mRecentQueue.empty()) {
4063 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
4064 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004065 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004066 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004067 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004068 }
4069 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004070 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004071 }
4072
4073 // Dump event currently being dispatched.
4074 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004075 dump += INDENT "PendingEvent:\n";
4076 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004077 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004078 dump += StringPrintf(", age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004079 (currentTime - mPendingEvent->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004080 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004081 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004082 }
4083
4084 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004085 if (!mInboundQueue.empty()) {
4086 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
4087 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004088 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004089 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004090 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004091 }
4092 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004093 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004094 }
4095
Michael Wright78f24442014-08-06 15:55:28 -07004096 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004097 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07004098 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
4099 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
4100 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004101 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n", i,
4102 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004103 }
4104 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004105 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004106 }
4107
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004108 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004109 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004110 for (const auto& pair : mConnectionsByFd) {
4111 const sp<Connection>& connection = pair.second;
4112 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
4113 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
4114 pair.first, connection->getInputChannelName().c_str(),
4115 connection->getWindowName().c_str(), connection->getStatusLabel(),
4116 toString(connection->monitor),
4117 toString(connection->inputPublisherBlocked));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004118
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004119 if (!connection->outboundQueue.empty()) {
4120 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4121 connection->outboundQueue.size());
4122 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004123 dump.append(INDENT4);
4124 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004125 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004126 entry->targetFlags, entry->resolvedAction,
4127 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004128 }
4129 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004130 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004131 }
4132
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004133 if (!connection->waitQueue.empty()) {
4134 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4135 connection->waitQueue.size());
4136 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004137 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004138 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004139 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004140 "age=%0.1fms, wait=%0.1fms\n",
4141 entry->targetFlags, entry->resolvedAction,
4142 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
4143 (currentTime - entry->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004144 }
4145 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004146 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004147 }
4148 }
4149 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004150 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004151 }
4152
4153 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004154 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004155 (mAppSwitchDueTime - now()) / 1000000.0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004156 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004157 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004158 }
4159
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004160 dump += INDENT "Configuration:\n";
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004161 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004162 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004163 mConfig.keyRepeatTimeout * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004164}
4165
Michael Wright3dd60e22019-03-27 22:06:44 +00004166void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4167 const size_t numMonitors = monitors.size();
4168 for (size_t i = 0; i < numMonitors; i++) {
4169 const Monitor& monitor = monitors[i];
4170 const sp<InputChannel>& channel = monitor.inputChannel;
4171 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4172 dump += "\n";
4173 }
4174}
4175
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004176status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004177#if DEBUG_REGISTRATION
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004178 ALOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004179#endif
4180
4181 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004182 std::scoped_lock _l(mLock);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004183 sp<Connection> existingConnection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004184 if (existingConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004185 ALOGW("Attempted to register already registered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004186 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004187 return BAD_VALUE;
4188 }
4189
Michael Wright3dd60e22019-03-27 22:06:44 +00004190 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004191
4192 int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004193 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004194 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004195
Michael Wrightd02c5b62014-02-10 15:10:22 -08004196 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4197 } // release lock
4198
4199 // Wake the looper because some connections have changed.
4200 mLooper->wake();
4201 return OK;
4202}
4203
Michael Wright3dd60e22019-03-27 22:06:44 +00004204status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004205 int32_t displayId, bool isGestureMonitor) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004206 { // acquire lock
4207 std::scoped_lock _l(mLock);
4208
4209 if (displayId < 0) {
4210 ALOGW("Attempted to register input monitor without a specified display.");
4211 return BAD_VALUE;
4212 }
4213
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004214 if (inputChannel->getConnectionToken() == nullptr) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004215 ALOGW("Attempted to register input monitor without an identifying token.");
4216 return BAD_VALUE;
4217 }
4218
4219 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
4220
4221 const int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004222 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004223 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004224
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004225 auto& monitorsByDisplay =
4226 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Michael Wright3dd60e22019-03-27 22:06:44 +00004227 monitorsByDisplay[displayId].emplace_back(inputChannel);
4228
4229 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004230 }
4231 // Wake the looper because some connections have changed.
4232 mLooper->wake();
4233 return OK;
4234}
4235
Michael Wrightd02c5b62014-02-10 15:10:22 -08004236status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
4237#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004238 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004239#endif
4240
4241 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004242 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004243
4244 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
4245 if (status) {
4246 return status;
4247 }
4248 } // release lock
4249
4250 // Wake the poll loop because removing the connection may have changed the current
4251 // synchronization state.
4252 mLooper->wake();
4253 return OK;
4254}
4255
4256status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004257 bool notify) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004258 sp<Connection> connection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004259 if (connection == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004260 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004261 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004262 return BAD_VALUE;
4263 }
4264
John Recke0710582019-09-26 13:46:12 -07004265 [[maybe_unused]] const bool removed = removeByValue(mConnectionsByFd, connection);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004266 ALOG_ASSERT(removed);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004267 mInputChannelsByToken.erase(inputChannel->getConnectionToken());
Robert Carr5c8a0262018-10-03 16:30:44 -07004268
Michael Wrightd02c5b62014-02-10 15:10:22 -08004269 if (connection->monitor) {
4270 removeMonitorChannelLocked(inputChannel);
4271 }
4272
4273 mLooper->removeFd(inputChannel->getFd());
4274
4275 nsecs_t currentTime = now();
4276 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4277
4278 connection->status = Connection::STATUS_ZOMBIE;
4279 return OK;
4280}
4281
4282void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004283 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4284 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4285}
4286
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004287void InputDispatcher::removeMonitorChannelLocked(
4288 const sp<InputChannel>& inputChannel,
Michael Wright3dd60e22019-03-27 22:06:44 +00004289 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004290 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004291 std::vector<Monitor>& monitors = it->second;
4292 const size_t numMonitors = monitors.size();
4293 for (size_t i = 0; i < numMonitors; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004294 if (monitors[i].inputChannel == inputChannel) {
4295 monitors.erase(monitors.begin() + i);
4296 break;
4297 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004298 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004299 if (monitors.empty()) {
4300 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004301 } else {
4302 ++it;
4303 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004304 }
4305}
4306
Michael Wright3dd60e22019-03-27 22:06:44 +00004307status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4308 { // acquire lock
4309 std::scoped_lock _l(mLock);
4310 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4311
4312 if (!foundDisplayId) {
4313 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4314 return BAD_VALUE;
4315 }
4316 int32_t displayId = foundDisplayId.value();
4317
4318 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4319 if (stateIndex < 0) {
4320 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4321 return BAD_VALUE;
4322 }
4323
4324 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4325 std::optional<int32_t> foundDeviceId;
4326 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004327 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004328 foundDeviceId = state.deviceId;
4329 }
4330 }
4331 if (!foundDeviceId || !state.down) {
4332 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004333 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004334 return BAD_VALUE;
4335 }
4336 int32_t deviceId = foundDeviceId.value();
4337
4338 // Send cancel events to all the input channels we're stealing from.
4339 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004340 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004341 options.deviceId = deviceId;
4342 options.displayId = displayId;
4343 for (const TouchedWindow& window : state.windows) {
4344 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004345 if (channel != nullptr) {
4346 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4347 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004348 }
4349 // Then clear the current touch state so we stop dispatching to them as well.
4350 state.filterNonMonitors();
4351 }
4352 return OK;
4353}
4354
Michael Wright3dd60e22019-03-27 22:06:44 +00004355std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4356 const sp<IBinder>& token) {
4357 for (const auto& it : mGestureMonitorsByDisplay) {
4358 const std::vector<Monitor>& monitors = it.second;
4359 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004360 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004361 return it.first;
4362 }
4363 }
4364 }
4365 return std::nullopt;
4366}
4367
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004368sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) {
4369 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004370 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004371 }
4372
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004373 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004374 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004375 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004376 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004377 }
4378 }
Robert Carr4e670e52018-08-15 13:26:12 -07004379
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004380 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004381}
4382
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004383void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4384 const sp<Connection>& connection, uint32_t seq,
4385 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004386 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4387 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004388 commandEntry->connection = connection;
4389 commandEntry->eventTime = currentTime;
4390 commandEntry->seq = seq;
4391 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004392 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004393}
4394
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004395void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4396 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004397 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004398 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004399
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004400 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4401 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004402 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004403 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004404}
4405
chaviw0c06c6e2019-01-09 13:27:07 -08004406void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004407 const sp<InputWindowHandle>& newFocus) {
chaviw0c06c6e2019-01-09 13:27:07 -08004408 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4409 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004410 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4411 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004412 commandEntry->oldToken = oldToken;
4413 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004414 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004415}
4416
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004417void InputDispatcher::onANRLocked(nsecs_t currentTime,
4418 const sp<InputApplicationHandle>& applicationHandle,
4419 const sp<InputWindowHandle>& windowHandle, nsecs_t eventTime,
4420 nsecs_t waitStartTime, const char* reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004421 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4422 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4423 ALOGI("Application is not responding: %s. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004424 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
4425 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), dispatchLatency,
4426 waitDuration, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004427
4428 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004429 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004430 struct tm tm;
4431 localtime_r(&t, &tm);
4432 char timestr[64];
4433 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4434 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004435 mLastANRState += INDENT "ANR:\n";
4436 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004437 mLastANRState +=
4438 StringPrintf(INDENT2 "Window: %s\n",
4439 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004440 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4441 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4442 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004443 dumpDispatchStateLocked(mLastANRState);
4444
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004445 std::unique_ptr<CommandEntry> commandEntry =
4446 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004447 commandEntry->inputApplicationHandle = applicationHandle;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004448 commandEntry->inputChannel =
4449 windowHandle != nullptr ? getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004450 commandEntry->reason = reason;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004451 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004452}
4453
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004454void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004455 mLock.unlock();
4456
4457 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4458
4459 mLock.lock();
4460}
4461
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004462void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004463 sp<Connection> connection = commandEntry->connection;
4464
4465 if (connection->status != Connection::STATUS_ZOMBIE) {
4466 mLock.unlock();
4467
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004468 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004469
4470 mLock.lock();
4471 }
4472}
4473
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004474void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004475 sp<IBinder> oldToken = commandEntry->oldToken;
4476 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004477 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004478 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004479 mLock.lock();
4480}
4481
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004482void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004483 sp<IBinder> token =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004484 commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004485 mLock.unlock();
4486
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004487 nsecs_t newTimeout =
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004488 mPolicy->notifyANR(commandEntry->inputApplicationHandle, token, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004489
4490 mLock.lock();
4491
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004492 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004493}
4494
4495void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4496 CommandEntry* commandEntry) {
4497 KeyEntry* entry = commandEntry->keyEntry;
4498
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004499 KeyEvent event = createKeyEvent(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004500
4501 mLock.unlock();
4502
Michael Wright2b3c3302018-03-02 17:19:13 +00004503 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004504 sp<IBinder> token = commandEntry->inputChannel != nullptr
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004505 ? commandEntry->inputChannel->getConnectionToken()
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004506 : nullptr;
4507 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004508 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4509 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004510 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004511 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004512
4513 mLock.lock();
4514
4515 if (delay < 0) {
4516 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4517 } else if (!delay) {
4518 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4519 } else {
4520 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4521 entry->interceptKeyWakeupTime = now() + delay;
4522 }
4523 entry->release();
4524}
4525
chaviwfd6d3512019-03-25 13:23:49 -07004526void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4527 mLock.unlock();
4528 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4529 mLock.lock();
4530}
4531
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004532void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004533 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004534 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004535 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004536 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004537
4538 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07004539 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004540 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004541 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004542 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004543 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004544
4545 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4546 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4547 std::string msg =
4548 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4549 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4550 dispatchEntry->eventEntry->appendDescription(msg);
4551 ALOGI("%s", msg.c_str());
4552 }
4553
4554 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004555 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004556 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4557 restartEvent =
4558 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004559 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004560 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4561 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4562 handled);
4563 } else {
4564 restartEvent = false;
4565 }
4566
4567 // Dequeue the event and start the next cycle.
4568 // Note that because the lock might have been released, it is possible that the
4569 // contents of the wait queue to have been drained, so we need to double-check
4570 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004571 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4572 if (dispatchEntryIt != connection->waitQueue.end()) {
4573 dispatchEntry = *dispatchEntryIt;
4574 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004575 traceWaitQueueLength(connection);
4576 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004577 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004578 traceOutboundQueueLength(connection);
4579 } else {
4580 releaseDispatchEntry(dispatchEntry);
4581 }
4582 }
4583
4584 // Start the next dispatch cycle for this connection.
4585 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004586}
4587
4588bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004589 DispatchEntry* dispatchEntry,
4590 KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004591 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004592 if (!handled) {
4593 // Report the key as unhandled, since the fallback was not handled.
4594 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4595 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004596 return false;
4597 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004598
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004599 // Get the fallback key state.
4600 // Clear it out after dispatching the UP.
4601 int32_t originalKeyCode = keyEntry->keyCode;
4602 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4603 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4604 connection->inputState.removeFallbackKey(originalKeyCode);
4605 }
4606
4607 if (handled || !dispatchEntry->hasForegroundTarget()) {
4608 // If the application handles the original key for which we previously
4609 // generated a fallback or if the window is not a foreground window,
4610 // then cancel the associated fallback key, if any.
4611 if (fallbackKeyCode != -1) {
4612 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004613#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004614 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004615 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4616 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4617 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004618#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004619 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004620 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004621
4622 mLock.unlock();
4623
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004624 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004625 keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004626
4627 mLock.lock();
4628
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004629 // Cancel the fallback key.
4630 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004631 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004632 "application handled the original non-fallback key "
4633 "or is no longer a foreground target, "
4634 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004635 options.keyCode = fallbackKeyCode;
4636 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004637 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004638 connection->inputState.removeFallbackKey(originalKeyCode);
4639 }
4640 } else {
4641 // If the application did not handle a non-fallback key, first check
4642 // that we are in a good state to perform unhandled key event processing
4643 // Then ask the policy what to do with it.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004644 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN && keyEntry->repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004645 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004646#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004647 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004648 "since this is not an initial down. "
4649 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4650 originalKeyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004651#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004652 return false;
4653 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004654
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004655 // Dispatch the unhandled key to the policy.
4656#if DEBUG_OUTBOUND_EVENT_DETAILS
4657 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004658 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4659 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004660#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004661 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004662
4663 mLock.unlock();
4664
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004665 bool fallback =
4666 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
4667 &event, keyEntry->policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004668
4669 mLock.lock();
4670
4671 if (connection->status != Connection::STATUS_NORMAL) {
4672 connection->inputState.removeFallbackKey(originalKeyCode);
4673 return false;
4674 }
4675
4676 // Latch the fallback keycode for this key on an initial down.
4677 // The fallback keycode cannot change at any other point in the lifecycle.
4678 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004679 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004680 fallbackKeyCode = event.getKeyCode();
4681 } else {
4682 fallbackKeyCode = AKEYCODE_UNKNOWN;
4683 }
4684 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4685 }
4686
4687 ALOG_ASSERT(fallbackKeyCode != -1);
4688
4689 // Cancel the fallback key if the policy decides not to send it anymore.
4690 // We will continue to dispatch the key to the policy but we will no
4691 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004692 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
4693 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004694#if DEBUG_OUTBOUND_EVENT_DETAILS
4695 if (fallback) {
4696 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004697 "as a fallback for %d, but on the DOWN it had requested "
4698 "to send %d instead. Fallback canceled.",
4699 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004700 } else {
4701 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004702 "but on the DOWN it had requested to send %d. "
4703 "Fallback canceled.",
4704 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004705 }
4706#endif
4707
4708 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4709 "canceling fallback, policy no longer desires it");
4710 options.keyCode = fallbackKeyCode;
4711 synthesizeCancelationEventsForConnectionLocked(connection, options);
4712
4713 fallback = false;
4714 fallbackKeyCode = AKEYCODE_UNKNOWN;
4715 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004716 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004717 }
4718 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004719
4720#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004721 {
4722 std::string msg;
4723 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4724 connection->inputState.getFallbackKeys();
4725 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004726 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004727 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004728 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004729 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004730 }
4731#endif
4732
4733 if (fallback) {
4734 // Restart the dispatch cycle using the fallback key.
4735 keyEntry->eventTime = event.getEventTime();
4736 keyEntry->deviceId = event.getDeviceId();
4737 keyEntry->source = event.getSource();
4738 keyEntry->displayId = event.getDisplayId();
4739 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4740 keyEntry->keyCode = fallbackKeyCode;
4741 keyEntry->scanCode = event.getScanCode();
4742 keyEntry->metaState = event.getMetaState();
4743 keyEntry->repeatCount = event.getRepeatCount();
4744 keyEntry->downTime = event.getDownTime();
4745 keyEntry->syntheticRepeat = false;
4746
4747#if DEBUG_OUTBOUND_EVENT_DETAILS
4748 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004749 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4750 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004751#endif
4752 return true; // restart the event
4753 } else {
4754#if DEBUG_OUTBOUND_EVENT_DETAILS
4755 ALOGD("Unhandled key event: No fallback key.");
4756#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004757
4758 // Report the key as unhandled, since there is no fallback key.
4759 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004760 }
4761 }
4762 return false;
4763}
4764
4765bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004766 DispatchEntry* dispatchEntry,
4767 MotionEntry* motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004768 return false;
4769}
4770
4771void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4772 mLock.unlock();
4773
4774 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4775
4776 mLock.lock();
4777}
4778
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004779KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
4780 KeyEvent event;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -06004781 event.initialize(entry.deviceId, entry.source, entry.displayId, INVALID_HMAC, entry.action,
4782 entry.flags, entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount,
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004783 entry.downTime, entry.eventTime);
4784 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004785}
4786
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004787void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004788 int32_t injectionResult,
4789 nsecs_t timeSpentWaitingForApplication) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004790 // TODO Write some statistics about how long we spend waiting.
4791}
4792
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05004793/**
4794 * Report the touch event latency to the statsd server.
4795 * Input events are reported for statistics if:
4796 * - This is a touchscreen event
4797 * - InputFilter is not enabled
4798 * - Event is not injected or synthesized
4799 *
4800 * Statistics should be reported before calling addValue, to prevent a fresh new sample
4801 * from getting aggregated with the "old" data.
4802 */
4803void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
4804 REQUIRES(mLock) {
4805 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
4806 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
4807 if (!reportForStatistics) {
4808 return;
4809 }
4810
4811 if (mTouchStatistics.shouldReport()) {
4812 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
4813 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
4814 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
4815 mTouchStatistics.reset();
4816 }
4817 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
4818 mTouchStatistics.addValue(latencyMicros);
4819}
4820
Michael Wrightd02c5b62014-02-10 15:10:22 -08004821void InputDispatcher::traceInboundQueueLengthLocked() {
4822 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004823 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004824 }
4825}
4826
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004827void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004828 if (ATRACE_ENABLED()) {
4829 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004830 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004831 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004832 }
4833}
4834
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004835void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004836 if (ATRACE_ENABLED()) {
4837 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004838 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004839 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004840 }
4841}
4842
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004843void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004844 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004845
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004846 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004847 dumpDispatchStateLocked(dump);
4848
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004849 if (!mLastANRState.empty()) {
4850 dump += "\nInput Dispatcher State at time of last ANR:\n";
4851 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004852 }
4853}
4854
4855void InputDispatcher::monitor() {
4856 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004857 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004858 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004859 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004860}
4861
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08004862/**
4863 * Wake up the dispatcher and wait until it processes all events and commands.
4864 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
4865 * this method can be safely called from any thread, as long as you've ensured that
4866 * the work you are interested in completing has already been queued.
4867 */
4868bool InputDispatcher::waitForIdle() {
4869 /**
4870 * Timeout should represent the longest possible time that a device might spend processing
4871 * events and commands.
4872 */
4873 constexpr std::chrono::duration TIMEOUT = 100ms;
4874 std::unique_lock lock(mLock);
4875 mLooper->wake();
4876 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
4877 return result == std::cv_status::no_timeout;
4878}
4879
Garfield Tane84e6f92019-08-29 17:28:41 -07004880} // namespace android::inputdispatcher