blob: 6ea64b440e464e37a4b6f438c2f476d8166dc9da [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>
Peter Collingbournec486ab32021-03-11 12:51:25 -080061#include <android-base/properties.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080062#include <android-base/stringprintf.h>
Robert Carr4e670e52018-08-15 13:26:12 -070063#include <binder/Binder.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080064#include <input/InputDevice.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070065#include <log/log.h>
Gang Wang342c9272020-01-13 13:15:04 -050066#include <openssl/hmac.h>
67#include <openssl/rand.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070068#include <powermanager/PowerManager.h>
69#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080070
71#define INDENT " "
72#define INDENT2 " "
73#define INDENT3 " "
74#define INDENT4 " "
75
Peter Collingbournec486ab32021-03-11 12:51:25 -080076using android::base::HwTimeoutMultiplier;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080077using android::base::StringPrintf;
78
Garfield Tane84e6f92019-08-29 17:28:41 -070079namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080080
81// Default input dispatching timeout if there is no focused application or paused window
82// from which to determine an appropriate dispatching timeout.
Peter Collingbournec486ab32021-03-11 12:51:25 -080083const std::chrono::nanoseconds DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5s * HwTimeoutMultiplier();
Michael Wrightd02c5b62014-02-10 15:10:22 -080084
85// Amount of time to allow for all pending events to be processed when an app switch
86// key is on the way. This is used to preempt input dispatch and drop input events
87// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000088constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080089
90// Amount of time to allow for an event to be dispatched (measured since its eventTime)
91// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000092constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080093
Michael Wrightd02c5b62014-02-10 15:10:22 -080094// 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 +000095constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
96
97// Log a warning when an interception call takes longer than this to process.
98constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -080099
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700100// Additional key latency in case a connection is still processing some motion events.
101// This will help with the case when a user touched a button that opens a new window,
102// and gives us the chance to dispatch the key to this new window.
103constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
104
Michael Wrightd02c5b62014-02-10 15:10:22 -0800105// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000106constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
107
Michael Wrightd02c5b62014-02-10 15:10:22 -0800108static inline nsecs_t now() {
109 return systemTime(SYSTEM_TIME_MONOTONIC);
110}
111
112static inline const char* toString(bool value) {
113 return value ? "true" : "false";
114}
115
116static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700117 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
118 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800119}
120
121static bool isValidKeyAction(int32_t action) {
122 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700123 case AKEY_EVENT_ACTION_DOWN:
124 case AKEY_EVENT_ACTION_UP:
125 return true;
126 default:
127 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800128 }
129}
130
131static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700132 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800133 ALOGE("Key event has invalid action code 0x%x", action);
134 return false;
135 }
136 return true;
137}
138
Michael Wright7b159c92015-05-14 14:48:03 +0100139static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800140 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700141 case AMOTION_EVENT_ACTION_DOWN:
142 case AMOTION_EVENT_ACTION_UP:
143 case AMOTION_EVENT_ACTION_CANCEL:
144 case AMOTION_EVENT_ACTION_MOVE:
145 case AMOTION_EVENT_ACTION_OUTSIDE:
146 case AMOTION_EVENT_ACTION_HOVER_ENTER:
147 case AMOTION_EVENT_ACTION_HOVER_MOVE:
148 case AMOTION_EVENT_ACTION_HOVER_EXIT:
149 case AMOTION_EVENT_ACTION_SCROLL:
150 return true;
151 case AMOTION_EVENT_ACTION_POINTER_DOWN:
152 case AMOTION_EVENT_ACTION_POINTER_UP: {
153 int32_t index = getMotionEventActionPointerIndex(action);
154 return index >= 0 && index < pointerCount;
155 }
156 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
157 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
158 return actionButton != 0;
159 default:
160 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800161 }
162}
163
Michael Wright7b159c92015-05-14 14:48:03 +0100164static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700165 const PointerProperties* pointerProperties) {
166 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800167 ALOGE("Motion event has invalid action code 0x%x", action);
168 return false;
169 }
170 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000171 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700172 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800173 return false;
174 }
175 BitSet32 pointerIdBits;
176 for (size_t i = 0; i < pointerCount; i++) {
177 int32_t id = pointerProperties[i].id;
178 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700179 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
180 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800181 return false;
182 }
183 if (pointerIdBits.hasBit(id)) {
184 ALOGE("Motion event has duplicate pointer id %d", id);
185 return false;
186 }
187 pointerIdBits.markBit(id);
188 }
189 return true;
190}
191
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800192static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800193 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800194 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800195 return;
196 }
197
198 bool first = true;
199 Region::const_iterator cur = region.begin();
200 Region::const_iterator const tail = region.end();
201 while (cur != tail) {
202 if (first) {
203 first = false;
204 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800205 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800206 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800207 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800208 cur++;
209 }
210}
211
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700212/**
213 * Find the entry in std::unordered_map by key, and return it.
214 * If the entry is not found, return a default constructed entry.
215 *
216 * Useful when the entries are vectors, since an empty vector will be returned
217 * if the entry is not found.
218 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
219 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700220template <typename K, typename V>
221static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700222 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700223 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800224}
225
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700226/**
227 * Find the entry in std::unordered_map by value, and remove it.
228 * If more than one entry has the same value, then all matching
229 * key-value pairs will be removed.
230 *
231 * Return true if at least one value has been removed.
232 */
233template <typename K, typename V>
234static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
235 bool removed = false;
236 for (auto it = map.begin(); it != map.end();) {
237 if (it->second == value) {
238 it = map.erase(it);
239 removed = true;
240 } else {
241 it++;
242 }
243 }
244 return removed;
245}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800246
chaviwaf87b3e2019-10-01 16:59:28 -0700247static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
248 if (first == second) {
249 return true;
250 }
251
252 if (first == nullptr || second == nullptr) {
253 return false;
254 }
255
256 return first->getToken() == second->getToken();
257}
258
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800259static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
260 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
261}
262
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000263static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
264 EventEntry* eventEntry,
265 int32_t inputTargetFlags) {
266 if (inputTarget.useDefaultPointerInfo()) {
267 const PointerInfo& pointerInfo = inputTarget.getDefaultPointerInfo();
268 return std::make_unique<DispatchEntry>(eventEntry, // increments ref
269 inputTargetFlags, pointerInfo.xOffset,
270 pointerInfo.yOffset, inputTarget.globalScaleFactor,
271 pointerInfo.windowXScale, pointerInfo.windowYScale);
272 }
273
274 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
275 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
276
277 PointerCoords pointerCoords[motionEntry.pointerCount];
278
279 // Use the first pointer information to normalize all other pointers. This could be any pointer
280 // as long as all other pointers are normalized to the same value and the final DispatchEntry
281 // uses the offset and scale for the normalized pointer.
282 const PointerInfo& firstPointerInfo =
283 inputTarget.pointerInfos[inputTarget.pointerIds.firstMarkedBit()];
284
285 // Iterate through all pointers in the event to normalize against the first.
286 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
287 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
288 uint32_t pointerId = uint32_t(pointerProperties.id);
289 const PointerInfo& currPointerInfo = inputTarget.pointerInfos[pointerId];
290
291 // The scale factor is the ratio of the current pointers scale to the normalized scale.
292 float scaleXDiff = currPointerInfo.windowXScale / firstPointerInfo.windowXScale;
293 float scaleYDiff = currPointerInfo.windowYScale / firstPointerInfo.windowYScale;
294
295 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
296 // First apply the current pointers offset to set the window at 0,0
297 pointerCoords[pointerIndex].applyOffset(currPointerInfo.xOffset, currPointerInfo.yOffset);
298 // Next scale the coordinates.
299 pointerCoords[pointerIndex].scale(1, scaleXDiff, scaleYDiff);
300 // Lastly, offset the coordinates so they're in the normalized pointer's frame.
301 pointerCoords[pointerIndex].applyOffset(-firstPointerInfo.xOffset,
302 -firstPointerInfo.yOffset);
303 }
304
305 MotionEntry* combinedMotionEntry =
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800306 new MotionEntry(motionEntry.id, motionEntry.eventTime, motionEntry.deviceId,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000307 motionEntry.source, motionEntry.displayId, motionEntry.policyFlags,
308 motionEntry.action, motionEntry.actionButton, motionEntry.flags,
309 motionEntry.metaState, motionEntry.buttonState,
310 motionEntry.classification, motionEntry.edgeFlags,
311 motionEntry.xPrecision, motionEntry.yPrecision,
312 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
313 motionEntry.downTime, motionEntry.pointerCount,
314 motionEntry.pointerProperties, pointerCoords, 0 /* xOffset */,
315 0 /* yOffset */);
316
317 if (motionEntry.injectionState) {
318 combinedMotionEntry->injectionState = motionEntry.injectionState;
319 combinedMotionEntry->injectionState->refCount += 1;
320 }
321
322 std::unique_ptr<DispatchEntry> dispatchEntry =
323 std::make_unique<DispatchEntry>(combinedMotionEntry, // increments ref
324 inputTargetFlags, firstPointerInfo.xOffset,
325 firstPointerInfo.yOffset, inputTarget.globalScaleFactor,
326 firstPointerInfo.windowXScale,
327 firstPointerInfo.windowYScale);
328 combinedMotionEntry->release();
329 return dispatchEntry;
330}
331
Siarhei Vishniakoue0fb6bd2020-04-13 11:40:37 -0700332static void addGestureMonitors(const std::vector<Monitor>& monitors,
333 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
334 float yOffset = 0) {
335 if (monitors.empty()) {
336 return;
337 }
338 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
339 for (const Monitor& monitor : monitors) {
340 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
341 }
342}
343
Gang Wang342c9272020-01-13 13:15:04 -0500344static std::array<uint8_t, 128> getRandomKey() {
345 std::array<uint8_t, 128> key;
346 if (RAND_bytes(key.data(), key.size()) != 1) {
347 LOG_ALWAYS_FATAL("Can't generate HMAC key");
348 }
349 return key;
350}
351
352// --- HmacKeyManager ---
353
354HmacKeyManager::HmacKeyManager() : mHmacKey(getRandomKey()) {}
355
356std::array<uint8_t, 32> HmacKeyManager::sign(const VerifiedInputEvent& event) const {
357 size_t size;
358 switch (event.type) {
359 case VerifiedInputEvent::Type::KEY: {
360 size = sizeof(VerifiedKeyEvent);
361 break;
362 }
363 case VerifiedInputEvent::Type::MOTION: {
364 size = sizeof(VerifiedMotionEvent);
365 break;
366 }
367 }
Gang Wang342c9272020-01-13 13:15:04 -0500368 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
Edgar Arriaga3d61bc12020-04-16 18:46:48 -0700369 return sign(start, size);
Gang Wang342c9272020-01-13 13:15:04 -0500370}
371
Edgar Arriaga3d61bc12020-04-16 18:46:48 -0700372std::array<uint8_t, 32> HmacKeyManager::sign(const uint8_t* data, size_t size) const {
Gang Wang342c9272020-01-13 13:15:04 -0500373 // SHA256 always generates 32-bytes result
374 std::array<uint8_t, 32> hash;
375 unsigned int hashLen = 0;
Edgar Arriaga3d61bc12020-04-16 18:46:48 -0700376 uint8_t* result =
377 HMAC(EVP_sha256(), mHmacKey.data(), mHmacKey.size(), data, size, hash.data(), &hashLen);
Gang Wang342c9272020-01-13 13:15:04 -0500378 if (result == nullptr) {
379 ALOGE("Could not sign the data using HMAC");
380 return INVALID_HMAC;
381 }
382
383 if (hashLen != hash.size()) {
384 ALOGE("HMAC-SHA256 has unexpected length");
385 return INVALID_HMAC;
386 }
387
388 return hash;
389}
390
Michael Wrightd02c5b62014-02-10 15:10:22 -0800391// --- InputDispatcher ---
392
Garfield Tan00f511d2019-06-12 16:55:40 -0700393InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
394 : mPolicy(policy),
395 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700396 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tan1c7bc862020-01-28 13:24:04 -0800397 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700398 mAppSwitchSawKeyDown(false),
399 mAppSwitchDueTime(LONG_LONG_MAX),
400 mNextUnblockedEvent(nullptr),
401 mDispatchEnabled(false),
402 mDispatchFrozen(false),
403 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800404 // mInTouchMode will be initialized by the WindowManager to the default device config.
405 // To avoid leaking stack in case that call never comes, and for tests,
406 // initialize it here anyways.
407 mInTouchMode(true),
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700408 mFocusedDisplayId(ADISPLAY_ID_DEFAULT) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800409 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800410 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800411
Yi Kong9b14ac62018-07-17 13:48:38 -0700412 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800413
414 policy->getDispatcherConfiguration(&mConfig);
415}
416
417InputDispatcher::~InputDispatcher() {
418 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800419 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800420
421 resetKeyRepeatLocked();
422 releasePendingEventLocked();
423 drainInboundQueueLocked();
424 }
425
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700426 while (!mConnectionsByFd.empty()) {
427 sp<Connection> connection = mConnectionsByFd.begin()->second;
428 unregisterInputChannel(connection->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800429 }
430}
431
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700432status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700433 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700434 return ALREADY_EXISTS;
435 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700436 mThread = std::make_unique<InputThread>(
437 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
438 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700439}
440
441status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700442 if (mThread && mThread->isCallingThread()) {
443 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700444 return INVALID_OPERATION;
445 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700446 mThread.reset();
447 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700448}
449
Michael Wrightd02c5b62014-02-10 15:10:22 -0800450void InputDispatcher::dispatchOnce() {
451 nsecs_t nextWakeupTime = LONG_LONG_MAX;
452 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800453 std::scoped_lock _l(mLock);
454 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800455
456 // Run a dispatch loop if there are no pending commands.
457 // The dispatch loop might enqueue commands to run afterwards.
458 if (!haveCommandsLocked()) {
459 dispatchOnceInnerLocked(&nextWakeupTime);
460 }
461
462 // Run all pending commands if there are any.
463 // If any commands were run then force the next poll to wake up immediately.
464 if (runCommandsLockedInterruptible()) {
465 nextWakeupTime = LONG_LONG_MIN;
466 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800467
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700468 // If we are still waiting for ack on some events,
469 // we might have to wake up earlier to check if an app is anr'ing.
470 const nsecs_t nextAnrCheck = processAnrsLocked();
471 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
472
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800473 // We are about to enter an infinitely long sleep, because we have no commands or
474 // pending or queued events
475 if (nextWakeupTime == LONG_LONG_MAX) {
476 mDispatcherEnteredIdle.notify_all();
477 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800478 } // release lock
479
480 // Wait for callback or timeout or wake. (make sure we round up, not down)
481 nsecs_t currentTime = now();
482 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
483 mLooper->pollOnce(timeoutMillis);
484}
485
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700486/**
Siarhei Vishniakou265ab012020-09-08 19:43:33 -0500487 * Raise ANR if there is no focused window.
488 * Before the ANR is raised, do a final state check:
489 * 1. The currently focused application must be the same one we are waiting for.
490 * 2. Ensure we still don't have a focused window.
491 */
492void InputDispatcher::processNoFocusedWindowAnrLocked() {
493 // Check if the application that we are waiting for is still focused.
494 sp<InputApplicationHandle> focusedApplication =
495 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
496 if (focusedApplication == nullptr ||
497 focusedApplication->getApplicationToken() !=
498 mAwaitedFocusedApplication->getApplicationToken()) {
499 // Unexpected because we should have reset the ANR timer when focused application changed
500 ALOGE("Waited for a focused window, but focused application has already changed to %s",
501 focusedApplication->getName().c_str());
502 return; // The focused application has changed.
503 }
504
505 const sp<InputWindowHandle>& focusedWindowHandle =
506 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
507 if (focusedWindowHandle != nullptr) {
508 return; // We now have a focused window. No need for ANR.
509 }
510 onAnrLocked(mAwaitedFocusedApplication);
511}
512
513/**
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700514 * Check if any of the connections' wait queues have events that are too old.
515 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
516 * Return the time at which we should wake up next.
517 */
518nsecs_t InputDispatcher::processAnrsLocked() {
519 const nsecs_t currentTime = now();
520 nsecs_t nextAnrCheck = LONG_LONG_MAX;
521 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
522 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
523 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakou265ab012020-09-08 19:43:33 -0500524 processNoFocusedWindowAnrLocked();
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700525 mAwaitedFocusedApplication.clear();
Siarhei Vishniakou265ab012020-09-08 19:43:33 -0500526 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700527 return LONG_LONG_MIN;
528 } else {
529 // Keep waiting
530 const nsecs_t millisRemaining = ns2ms(*mNoFocusedWindowTimeoutTime - currentTime);
531 ALOGW("Still no focused window. Will drop the event in %" PRId64 "ms", millisRemaining);
532 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
533 }
534 }
535
536 // Check if any connection ANRs are due
537 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
538 if (currentTime < nextAnrCheck) { // most likely scenario
539 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
540 }
541
542 // If we reached here, we have an unresponsive connection.
543 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
544 if (connection == nullptr) {
545 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
546 return nextAnrCheck;
547 }
548 connection->responsive = false;
549 // Stop waking up for this unresponsive connection
550 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4e219792020-09-22 21:43:09 -0500551 onAnrLocked(*connection);
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700552 return LONG_LONG_MIN;
553}
554
555nsecs_t InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
556 sp<InputWindowHandle> window = getWindowHandleLocked(token);
557 if (window != nullptr) {
558 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT).count();
559 }
560 return DEFAULT_INPUT_DISPATCHING_TIMEOUT.count();
561}
562
Michael Wrightd02c5b62014-02-10 15:10:22 -0800563void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
564 nsecs_t currentTime = now();
565
Jeff Browndc5992e2014-04-11 01:27:26 -0700566 // Reset the key repeat timer whenever normal dispatch is suspended while the
567 // device is in a non-interactive state. This is to ensure that we abort a key
568 // repeat if the device is just coming out of sleep.
569 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800570 resetKeyRepeatLocked();
571 }
572
573 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
574 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100575 if (DEBUG_FOCUS) {
576 ALOGD("Dispatch frozen. Waiting some more.");
577 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800578 return;
579 }
580
581 // Optimize latency of app switches.
582 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
583 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
584 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
585 if (mAppSwitchDueTime < *nextWakeupTime) {
586 *nextWakeupTime = mAppSwitchDueTime;
587 }
588
589 // Ready to start a new event.
590 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700591 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700592 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800593 if (isAppSwitchDue) {
594 // The inbound queue is empty so the app switch key we were waiting
595 // for will never arrive. Stop waiting for it.
596 resetPendingAppSwitchLocked(false);
597 isAppSwitchDue = false;
598 }
599
600 // Synthesize a key repeat if appropriate.
601 if (mKeyRepeatState.lastKeyEntry) {
602 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
603 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
604 } else {
605 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
606 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
607 }
608 }
609 }
610
611 // Nothing to do if there is no pending event.
612 if (!mPendingEvent) {
613 return;
614 }
615 } else {
616 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700617 mPendingEvent = mInboundQueue.front();
618 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800619 traceInboundQueueLengthLocked();
620 }
621
622 // Poke user activity for this event.
623 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700624 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800625 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800626 }
627
628 // Now we have an event to dispatch.
629 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700630 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800631 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700632 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800633 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700634 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800635 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700636 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800637 }
638
639 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700640 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800641 }
642
643 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700644 case EventEntry::Type::CONFIGURATION_CHANGED: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700645 ConfigurationChangedEntry* typedEntry =
646 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
647 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700648 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700649 break;
650 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800651
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700652 case EventEntry::Type::DEVICE_RESET: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700653 DeviceResetEntry* typedEntry = static_cast<DeviceResetEntry*>(mPendingEvent);
654 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700655 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700656 break;
657 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800658
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100659 case EventEntry::Type::FOCUS: {
660 FocusEntry* typedEntry = static_cast<FocusEntry*>(mPendingEvent);
661 dispatchFocusLocked(currentTime, typedEntry);
662 done = true;
663 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
664 break;
665 }
666
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700667 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700668 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
669 if (isAppSwitchDue) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700670 if (isAppSwitchKeyEvent(*typedEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700671 resetPendingAppSwitchLocked(true);
672 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700673 } else if (dropReason == DropReason::NOT_DROPPED) {
674 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700675 }
676 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700677 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700678 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700679 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700680 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
681 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700682 }
683 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
684 break;
685 }
686
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700687 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700688 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700689 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
690 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800691 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700692 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *typedEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700693 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700694 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700695 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
696 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700697 }
698 done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
699 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800700 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800701 }
702
703 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700704 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700705 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800706 }
Michael Wright3a981722015-06-10 15:26:13 +0100707 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800708
709 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700710 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800711 }
712}
713
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -0700714/**
715 * Return true if the events preceding this incoming motion event should be dropped
716 * Return false otherwise (the default behaviour)
717 */
718bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700719 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -0700720 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700721
722 // Optimize case where the current application is unresponsive and the user
723 // decides to touch a window in a different application.
724 // If the application takes too long to catch up then we drop all events preceding
725 // the touch into the other window.
726 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -0700727 int32_t displayId = motionEntry.displayId;
728 int32_t x = static_cast<int32_t>(
729 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
730 int32_t y = static_cast<int32_t>(
731 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -0700732 sp<InputWindowHandle> touchedWindowHandle =
733 findTouchedWindowAtLocked(displayId, x, y, nullptr);
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -0700734 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700735 touchedWindowHandle->getApplicationToken() !=
736 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -0700737 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700738 ALOGI("Pruning input queue because user touched a different application while waiting "
739 "for %s",
740 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -0700741 return true;
742 }
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700743
744 // Alternatively, maybe there's a gesture monitor that could handle this event
745 std::vector<TouchedMonitor> gestureMonitors =
746 findTouchedGestureMonitorsLocked(displayId, {});
747 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
748 sp<Connection> connection =
749 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000750 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoue4623042020-03-25 16:16:40 -0700751 // This monitor could take more input. Drop all events preceding this
752 // event, so that gesture monitor could get a chance to receive the stream
753 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
754 "responsive gesture monitor that may handle the event",
755 mAwaitedFocusedApplication->getName().c_str());
756 return true;
757 }
758 }
759 }
760
761 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
762 // yet been processed by some connections, the dispatcher will wait for these motion
763 // events to be processed before dispatching the key event. This is because these motion events
764 // may cause a new window to be launched, which the user might expect to receive focus.
765 // To prevent waiting forever for such events, just send the key to the currently focused window
766 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
767 ALOGD("Received a new pointer down event, stop waiting for events to process and "
768 "just send the pending key event to the focused window.");
769 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -0700770 }
771 return false;
772}
773
Michael Wrightd02c5b62014-02-10 15:10:22 -0800774bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700775 bool needWake = mInboundQueue.empty();
776 mInboundQueue.push_back(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800777 traceInboundQueueLengthLocked();
778
779 switch (entry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700780 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700781 // Optimize app switch latency.
782 // If the application takes too long to catch up then we drop all events preceding
783 // the app switch key.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700784 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700785 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700786 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700787 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700788 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700789 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800790#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700791 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800792#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700793 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700794 mAppSwitchSawKeyDown = false;
795 needWake = true;
796 }
797 }
798 }
799 break;
800 }
801
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700802 case EventEntry::Type::MOTION: {
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -0700803 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(*entry))) {
804 mNextUnblockedEvent = entry;
805 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800806 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700807 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800808 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100809 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -0700810 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
811 break;
812 }
813 case EventEntry::Type::CONFIGURATION_CHANGED:
814 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700815 // nothing to do
816 break;
817 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800818 }
819
820 return needWake;
821}
822
823void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
824 entry->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700825 mRecentQueue.push_back(entry);
826 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
827 mRecentQueue.front()->release();
828 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800829 }
830}
831
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700832sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -0700833 int32_t y, TouchState* touchState,
834 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700835 bool addPortalWindows) {
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -0700836 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
837 LOG_ALWAYS_FATAL(
838 "Must provide a valid touch state if adding portal windows or outside targets");
839 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800840 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800841 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
842 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800843 const InputWindowInfo* windowInfo = windowHandle->getInfo();
844 if (windowInfo->displayId == displayId) {
845 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800846
847 if (windowInfo->visible) {
848 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700849 bool isTouchModal = (flags &
850 (InputWindowInfo::FLAG_NOT_FOCUSABLE |
851 InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800852 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800853 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700854 if (portalToDisplayId != ADISPLAY_ID_NONE &&
855 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800856 if (addPortalWindows) {
857 // For the monitoring channels of the display.
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -0700858 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800859 }
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -0700860 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700861 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800862 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800863 // Found window.
864 return windowHandle;
865 }
866 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800867
868 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -0700869 touchState->addOrUpdateWindow(windowHandle,
870 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
871 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800872 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800873 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800874 }
875 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700876 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800877}
878
Garfield Tane84e6f92019-08-29 17:28:41 -0700879std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakoue0fb6bd2020-04-13 11:40:37 -0700880 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000881 std::vector<TouchedMonitor> touchedMonitors;
882
883 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
884 addGestureMonitors(monitors, touchedMonitors);
885 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
886 const InputWindowInfo* windowInfo = portalWindow->getInfo();
887 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700888 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
889 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000890 }
891 return touchedMonitors;
892}
893
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700894void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800895 const char* reason;
896 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700897 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800898#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700899 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800900#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700901 reason = "inbound event was dropped because the policy consumed it";
902 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700903 case DropReason::DISABLED:
904 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700905 ALOGI("Dropped event because input dispatch is disabled.");
906 }
907 reason = "inbound event was dropped because input dispatch is disabled";
908 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700909 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700910 ALOGI("Dropped event because of pending overdue app switch.");
911 reason = "inbound event was dropped because of pending overdue app switch";
912 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700913 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700914 ALOGI("Dropped event because the current application is not responding and the user "
915 "has started interacting with a different application.");
916 reason = "inbound event was dropped because the current application is not responding "
917 "and the user has started interacting with a different application";
918 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700919 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700920 ALOGI("Dropped event because it is stale.");
921 reason = "inbound event was dropped because it is stale";
922 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700923 case DropReason::NOT_DROPPED: {
924 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700925 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700926 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800927 }
928
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700929 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700930 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800931 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
932 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700933 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800934 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700935 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700936 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
937 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700938 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
939 synthesizeCancelationEventsForAllConnectionsLocked(options);
940 } else {
941 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
942 synthesizeCancelationEventsForAllConnectionsLocked(options);
943 }
944 break;
945 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100946 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700947 case EventEntry::Type::CONFIGURATION_CHANGED:
948 case EventEntry::Type::DEVICE_RESET: {
949 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
950 break;
951 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800952 }
953}
954
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800955static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700956 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
957 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800958}
959
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700960bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
961 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
962 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
963 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800964}
965
966bool InputDispatcher::isAppSwitchPendingLocked() {
967 return mAppSwitchDueTime != LONG_LONG_MAX;
968}
969
970void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
971 mAppSwitchDueTime = LONG_LONG_MAX;
972
973#if DEBUG_APP_SWITCH
974 if (handled) {
975 ALOGD("App switch has arrived.");
976 } else {
977 ALOGD("App switch was abandoned.");
978 }
979#endif
980}
981
Michael Wrightd02c5b62014-02-10 15:10:22 -0800982bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700983 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800984}
985
986bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700987 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800988 return false;
989 }
990
991 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700992 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700993 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800994 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700995 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800996
997 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700998 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800999 return true;
1000}
1001
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001002void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1003 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001004}
1005
1006void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001007 while (!mInboundQueue.empty()) {
1008 EventEntry* entry = mInboundQueue.front();
1009 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001010 releaseInboundEventLocked(entry);
1011 }
1012 traceInboundQueueLengthLocked();
1013}
1014
1015void InputDispatcher::releasePendingEventLocked() {
1016 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001017 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001018 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001019 }
1020}
1021
1022void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
1023 InjectionState* injectionState = entry->injectionState;
1024 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1025#if DEBUG_DISPATCH_CYCLE
1026 ALOGD("Injected inbound event was dropped.");
1027#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001028 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001029 }
1030 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001031 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001032 }
1033 addRecentEventLocked(entry);
1034 entry->release();
1035}
1036
1037void InputDispatcher::resetKeyRepeatLocked() {
1038 if (mKeyRepeatState.lastKeyEntry) {
1039 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -07001040 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001041 }
1042}
1043
Garfield Tane84e6f92019-08-29 17:28:41 -07001044KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001045 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
1046
1047 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -07001048 uint32_t policyFlags = entry->policyFlags &
1049 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001050 if (entry->refCount == 1) {
1051 entry->recycle();
Garfield Tan1c7bc862020-01-28 13:24:04 -08001052 entry->id = mIdGenerator.nextId();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001053 entry->eventTime = currentTime;
1054 entry->policyFlags = policyFlags;
1055 entry->repeatCount += 1;
1056 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001057 KeyEntry* newEntry =
Garfield Tan1c7bc862020-01-28 13:24:04 -08001058 new KeyEntry(mIdGenerator.nextId(), currentTime, entry->deviceId, entry->source,
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001059 entry->displayId, policyFlags, entry->action, entry->flags,
1060 entry->keyCode, entry->scanCode, entry->metaState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001061 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001062
1063 mKeyRepeatState.lastKeyEntry = newEntry;
1064 entry->release();
1065
1066 entry = newEntry;
1067 }
1068 entry->syntheticRepeat = true;
1069
1070 // Increment reference count since we keep a reference to the event in
1071 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
1072 entry->refCount += 1;
1073
1074 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
1075 return entry;
1076}
1077
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001078bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
1079 ConfigurationChangedEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07001081 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001082#endif
1083
1084 // Reset key repeating in case a keyboard device was added or removed or something.
1085 resetKeyRepeatLocked();
1086
1087 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001088 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1089 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001090 commandEntry->eventTime = entry->eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001091 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001092 return true;
1093}
1094
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001095bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceResetEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001096#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07001097 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001098 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001099#endif
1100
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001101 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001102 options.deviceId = entry->deviceId;
1103 synthesizeCancelationEventsForAllConnectionsLocked(options);
1104 return true;
1105}
1106
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001107void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) {
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -07001108 if (mPendingEvent != nullptr) {
1109 // Move the pending event to the front of the queue. This will give the chance
1110 // for the pending event to get dispatched to the newly focused window
1111 mInboundQueue.push_front(mPendingEvent);
1112 mPendingEvent = nullptr;
1113 }
1114
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001115 FocusEntry* focusEntry =
Garfield Tan1c7bc862020-01-28 13:24:04 -08001116 new FocusEntry(mIdGenerator.nextId(), now(), window.getToken(), hasFocus);
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -07001117
1118 // This event should go to the front of the queue, but behind all other focus events
1119 // Find the last focus event, and insert right after it
1120 std::deque<EventEntry*>::reverse_iterator it =
1121 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
1122 [](EventEntry* event) { return event->type == EventEntry::Type::FOCUS; });
1123
1124 // Maintain the order of focus events. Insert the entry after all other focus events.
1125 mInboundQueue.insert(it.base(), focusEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001126}
1127
1128void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) {
1129 sp<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1130 if (channel == nullptr) {
1131 return; // Window has gone away
1132 }
1133 InputTarget target;
1134 target.inputChannel = channel;
1135 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1136 entry->dispatchInProgress = true;
Selim Cinek3d989c22020-06-17 21:42:12 +00001137
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001138 dispatchEventLocked(currentTime, entry, {target});
1139}
1140
Michael Wrightd02c5b62014-02-10 15:10:22 -08001141bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001142 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001143 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001144 if (!entry->dispatchInProgress) {
1145 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1146 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1147 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1148 if (mKeyRepeatState.lastKeyEntry &&
1149 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001150 // We have seen two identical key downs in a row which indicates that the device
1151 // driver is automatically generating key repeats itself. We take note of the
1152 // repeat here, but we disable our own next key repeat timer since it is clear that
1153 // we will not need to synthesize key repeats ourselves.
1154 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1155 resetKeyRepeatLocked();
1156 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1157 } else {
1158 // Not a repeat. Save key down state in case we do see a repeat later.
1159 resetKeyRepeatLocked();
1160 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1161 }
1162 mKeyRepeatState.lastKeyEntry = entry;
1163 entry->refCount += 1;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001164 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001165 resetKeyRepeatLocked();
1166 }
1167
1168 if (entry->repeatCount == 1) {
1169 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1170 } else {
1171 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1172 }
1173
1174 entry->dispatchInProgress = true;
1175
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001176 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001177 }
1178
1179 // Handle case where the policy asked us to try again later last time.
1180 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1181 if (currentTime < entry->interceptKeyWakeupTime) {
1182 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1183 *nextWakeupTime = entry->interceptKeyWakeupTime;
1184 }
1185 return false; // wait until next wakeup
1186 }
1187 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1188 entry->interceptKeyWakeupTime = 0;
1189 }
1190
1191 // Give the policy a chance to intercept the key.
1192 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1193 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001194 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001195 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +08001196 sp<InputWindowHandle> focusedWindowHandle =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001197 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(*entry));
Tiger Huang721e26f2018-07-24 22:26:19 +08001198 if (focusedWindowHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001199 commandEntry->inputChannel = getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001200 }
1201 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001202 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001203 entry->refCount += 1;
1204 return false; // wait for the command to run
1205 } else {
1206 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1207 }
1208 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001209 if (*dropReason == DropReason::NOT_DROPPED) {
1210 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001211 }
1212 }
1213
1214 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001215 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001216 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001217 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001218 : INPUT_EVENT_INJECTION_FAILED);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001219 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001220 return true;
1221 }
1222
1223 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001224 std::vector<InputTarget> inputTargets;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001225 int32_t injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001226 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001227 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1228 return false;
1229 }
1230
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001231 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001232 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
1233 return true;
1234 }
1235
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001236 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001237 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001238
1239 // Dispatch the key.
1240 dispatchEventLocked(currentTime, entry, inputTargets);
1241 return true;
1242}
1243
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001244void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001245#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001246 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001247 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1248 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001249 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1250 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1251 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001252#endif
1253}
1254
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001255bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry,
1256 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001257 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001258 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001259 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001260 entry->dispatchInProgress = true;
1261
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001262 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001263 }
1264
1265 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001266 if (*dropReason != DropReason::NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001267 setInjectionResult(entry,
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001268 *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001269 : INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001270 return true;
1271 }
1272
1273 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1274
1275 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001276 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001277
1278 bool conflictingPointerActions = false;
1279 int32_t injectionResult;
1280 if (isPointerEvent) {
1281 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001282 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001283 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001284 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001285 } else {
1286 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001287 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001288 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001289 }
1290 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1291 return false;
1292 }
1293
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001294 setInjectionResult(entry, injectionResult);
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07001295 if (injectionResult == INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
1296 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1297 return true;
1298 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001299 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07001300 CancelationOptions::Mode mode(isPointerEvent
1301 ? CancelationOptions::CANCEL_POINTER_EVENTS
1302 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1303 CancelationOptions options(mode, "input event injection failed");
1304 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001305 return true;
1306 }
1307
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001308 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001309 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001310
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001311 if (isPointerEvent) {
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07001312 std::unordered_map<int32_t, TouchState>::iterator it =
1313 mTouchStatesByDisplay.find(entry->displayId);
1314 if (it != mTouchStatesByDisplay.end()) {
1315 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001316 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001317 // The event has gone through these portal windows, so we add monitoring targets of
1318 // the corresponding displays as well.
1319 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001320 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001321 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001322 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001323 }
1324 }
1325 }
1326 }
1327
Michael Wrightd02c5b62014-02-10 15:10:22 -08001328 // Dispatch the motion.
1329 if (conflictingPointerActions) {
1330 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001331 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001332 synthesizeCancelationEventsForAllConnectionsLocked(options);
1333 }
1334 dispatchEventLocked(currentTime, entry, inputTargets);
1335 return true;
1336}
1337
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001338void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001339#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001340 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001341 ", policyFlags=0x%x, "
1342 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1343 "metaState=0x%x, buttonState=0x%x,"
1344 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001345 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1346 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1347 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001348
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001349 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001350 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001351 "x=%f, y=%f, pressure=%f, size=%f, "
1352 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1353 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001354 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1355 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1356 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1357 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1358 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1359 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1360 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1361 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1362 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1363 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001364 }
1365#endif
1366}
1367
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001368void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* eventEntry,
1369 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001370 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001371#if DEBUG_DISPATCH_CYCLE
1372 ALOGD("dispatchEventToCurrentInputTargets");
1373#endif
1374
1375 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1376
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001377 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001378
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001379 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001380 sp<Connection> connection =
1381 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001382 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001383 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001384 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001385 if (DEBUG_FOCUS) {
1386 ALOGD("Dropping event delivery to target with channel '%s' because it "
1387 "is no longer registered with the input dispatcher.",
1388 inputTarget.inputChannel->getName().c_str());
1389 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001390 }
1391 }
1392}
1393
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07001394void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1395 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1396 // If the policy decides to close the app, we will get a channel removal event via
1397 // unregisterInputChannel, and will clean up the connection that way. We are already not
1398 // sending new pointers to the connection when it blocked, but focused events will continue to
1399 // pile up.
1400 ALOGW("Canceling events for %s because it is unresponsive",
1401 connection->inputChannel->getName().c_str());
1402 if (connection->status == Connection::STATUS_NORMAL) {
1403 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1404 "application not responding");
1405 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001406 }
1407}
1408
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07001409void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001410 if (DEBUG_FOCUS) {
1411 ALOGD("Resetting ANR timeouts.");
1412 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001413
1414 // Reset input target wait timeout.
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07001415 mNoFocusedWindowTimeoutTime = std::nullopt;
1416 mAwaitedFocusedApplication.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001417}
1418
Tiger Huang721e26f2018-07-24 22:26:19 +08001419/**
1420 * Get the display id that the given event should go to. If this event specifies a valid display id,
1421 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1422 * Focused display is the display that the user most recently interacted with.
1423 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001424int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001425 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001426 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001427 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001428 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1429 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001430 break;
1431 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001432 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001433 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1434 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001435 break;
1436 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001437 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001438 case EventEntry::Type::CONFIGURATION_CHANGED:
1439 case EventEntry::Type::DEVICE_RESET: {
1440 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001441 return ADISPLAY_ID_NONE;
1442 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001443 }
1444 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1445}
1446
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07001447bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1448 const char* focusedWindowName) {
1449 if (mAnrTracker.empty()) {
1450 // already processed all events that we waited for
1451 mKeyIsWaitingForEventsTimeout = std::nullopt;
1452 return false;
1453 }
1454
1455 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1456 // Start the timer
1457 ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
1458 "focus to change",
1459 focusedWindowName);
1460 mKeyIsWaitingForEventsTimeout = currentTime + KEY_WAITING_FOR_EVENTS_TIMEOUT.count();
1461 return true;
1462 }
1463
1464 // We still have pending events, and already started the timer
1465 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1466 return true; // Still waiting
1467 }
1468
1469 // Waited too long, and some connection still hasn't processed all motions
1470 // Just send the key to the focused window
1471 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1472 focusedWindowName);
1473 mKeyIsWaitingForEventsTimeout = std::nullopt;
1474 return false;
1475}
1476
Michael Wrightd02c5b62014-02-10 15:10:22 -08001477int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001478 const EventEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001479 std::vector<InputTarget>& inputTargets,
1480 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001481 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001482
Tiger Huang721e26f2018-07-24 22:26:19 +08001483 int32_t displayId = getTargetDisplayId(entry);
1484 sp<InputWindowHandle> focusedWindowHandle =
1485 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1486 sp<InputApplicationHandle> focusedApplicationHandle =
1487 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1488
Michael Wrightd02c5b62014-02-10 15:10:22 -08001489 // If there is no currently focused window and no focused application
1490 // then drop the event.
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07001491 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1492 ALOGI("Dropping %s event because there is no focused window or focused application in "
1493 "display %" PRId32 ".",
1494 EventEntry::typeToString(entry.type), displayId);
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07001495 return INPUT_EVENT_INJECTION_FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001496 }
1497
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07001498 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1499 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1500 // start interacting with another application via touch (app switch). This code can be removed
1501 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1502 // an app is expected to have a focused window.
1503 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1504 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1505 // We just discovered that there's no focused window. Start the ANR timer
1506 const nsecs_t timeout = focusedApplicationHandle->getDispatchingTimeout(
1507 DEFAULT_INPUT_DISPATCHING_TIMEOUT.count());
1508 mNoFocusedWindowTimeoutTime = currentTime + timeout;
1509 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakou265ab012020-09-08 19:43:33 -05001510 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07001511 ALOGW("Waiting because no window has focus but %s may eventually add a "
1512 "window when it finishes starting up. Will wait for %" PRId64 "ms",
1513 mAwaitedFocusedApplication->getName().c_str(), ns2ms(timeout));
1514 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
1515 return INPUT_EVENT_INJECTION_PENDING;
1516 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1517 // Already raised ANR. Drop the event
1518 ALOGE("Dropping %s event because there is no focused window",
1519 EventEntry::typeToString(entry.type));
1520 return INPUT_EVENT_INJECTION_FAILED;
1521 } else {
1522 // Still waiting for the focused window
1523 return INPUT_EVENT_INJECTION_PENDING;
1524 }
1525 }
1526
1527 // we have a valid, non-null focused window
1528 resetNoFocusedWindowTimeoutLocked();
1529
Michael Wrightd02c5b62014-02-10 15:10:22 -08001530 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001531 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07001532 return INPUT_EVENT_INJECTION_PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001533 }
1534
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07001535 if (focusedWindowHandle->getInfo()->paused) {
1536 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
1537 return INPUT_EVENT_INJECTION_PENDING;
1538 }
1539
1540 // If the event is a key event, then we must wait for all previous events to
1541 // complete before delivering it because previous events may have the
1542 // side-effect of transferring focus to a different window and we want to
1543 // ensure that the following keys are sent to the new window.
1544 //
1545 // Suppose the user touches a button in a window then immediately presses "A".
1546 // If the button causes a pop-up window to appear then we want to ensure that
1547 // the "A" key is delivered to the new pop-up window. This is because users
1548 // often anticipate pending UI changes when typing on a keyboard.
1549 // To obtain this behavior, we must serialize key events with respect to all
1550 // prior input events.
1551 if (entry.type == EventEntry::Type::KEY) {
1552 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1553 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
1554 return INPUT_EVENT_INJECTION_PENDING;
1555 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001556 }
1557
1558 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001559 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001560 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1561 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001562
1563 // Done.
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07001564 return INPUT_EVENT_INJECTION_SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001565}
1566
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07001567/**
1568 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1569 * that are currently unresponsive.
1570 */
1571std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1572 const std::vector<TouchedMonitor>& monitors) const {
1573 std::vector<TouchedMonitor> responsiveMonitors;
1574 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1575 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1576 sp<Connection> connection = getConnectionLocked(
1577 monitor.monitor.inputChannel->getConnectionToken());
1578 if (connection == nullptr) {
1579 ALOGE("Could not find connection for monitor %s",
1580 monitor.monitor.inputChannel->getName().c_str());
1581 return false;
1582 }
1583 if (!connection->responsive) {
1584 ALOGW("Unresponsive monitor %s will not get the new gesture",
1585 connection->inputChannel->getName().c_str());
1586 return false;
1587 }
1588 return true;
1589 });
1590 return responsiveMonitors;
1591}
1592
Michael Wrightd02c5b62014-02-10 15:10:22 -08001593int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001594 const MotionEntry& entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001595 std::vector<InputTarget>& inputTargets,
1596 nsecs_t* nextWakeupTime,
1597 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001598 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001599 enum InjectionPermission {
1600 INJECTION_PERMISSION_UNKNOWN,
1601 INJECTION_PERMISSION_GRANTED,
1602 INJECTION_PERMISSION_DENIED
1603 };
1604
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605 // For security reasons, we defer updating the touch state until we are sure that
1606 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001607 int32_t displayId = entry.displayId;
1608 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001609 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1610
1611 // Update the touch state as needed based on the properties of the touch event.
1612 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1613 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1614 sp<InputWindowHandle> newHoverWindowHandle;
1615
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001616 // Copy current touch state into tempTouchState.
1617 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1618 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001619 const TouchState* oldState = nullptr;
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001620 TouchState tempTouchState;
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07001621 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1622 mTouchStatesByDisplay.find(displayId);
1623 if (oldStateIt != mTouchStatesByDisplay.end()) {
1624 oldState = &(oldStateIt->second);
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001625 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001626 }
1627
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001628 bool isSplit = tempTouchState.split;
1629 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1630 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1631 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001632 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1633 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1634 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1635 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1636 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001637 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001638 bool wrongDevice = false;
1639 if (newGesture) {
1640 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001641 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakoue0fb6bd2020-04-13 11:40:37 -07001642 ALOGI("Dropping event because a pointer for a different device is already down "
1643 "in display %" PRId32,
1644 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001645 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001646 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1647 switchedDevice = false;
1648 wrongDevice = true;
1649 goto Failed;
1650 }
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001651 tempTouchState.reset();
1652 tempTouchState.down = down;
1653 tempTouchState.deviceId = entry.deviceId;
1654 tempTouchState.source = entry.source;
1655 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001656 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001657 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakoue0fb6bd2020-04-13 11:40:37 -07001658 ALOGI("Dropping move event because a pointer for a different device is already active "
1659 "in display %" PRId32,
1660 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001661 // TODO: test multiple simultaneous input streams.
1662 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1663 switchedDevice = false;
1664 wrongDevice = true;
1665 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001666 }
1667
1668 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1669 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1670
Garfield Tan00f511d2019-06-12 16:55:40 -07001671 int32_t x;
1672 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001673 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001674 // Always dispatch mouse events to cursor position.
1675 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001676 x = int32_t(entry.xCursorPosition);
1677 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001678 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001679 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1680 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001681 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001682 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001683 sp<InputWindowHandle> newTouchedWindowHandle =
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001684 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1685 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001686
1687 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001688 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001689 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001690
Michael Wrightd02c5b62014-02-10 15:10:22 -08001691 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001692 if (newTouchedWindowHandle != nullptr &&
1693 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001694 // New window supports splitting, but we should never split mouse events.
1695 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001696 } else if (isSplit) {
1697 // New window does not support splitting but we have already split events.
1698 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001699 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001700 }
1701
1702 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001703 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001704 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001705 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001706 }
1707
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07001708 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1709 ALOGI("Not sending touch event to %s because it is paused",
1710 newTouchedWindowHandle->getName().c_str());
1711 newTouchedWindowHandle = nullptr;
1712 }
1713
1714 if (newTouchedWindowHandle != nullptr) {
1715 sp<Connection> connection = getConnectionLocked(newTouchedWindowHandle->getToken());
1716 if (connection == nullptr) {
1717 ALOGI("Could not find connection for %s",
1718 newTouchedWindowHandle->getName().c_str());
1719 newTouchedWindowHandle = nullptr;
1720 } else if (!connection->responsive) {
1721 // don't send the new touch to an unresponsive window
1722 ALOGW("Unresponsive window %s will not get the new gesture at %" PRIu64,
1723 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1724 newTouchedWindowHandle = nullptr;
1725 }
1726 }
1727
1728 // Also don't send the new touch event to unresponsive gesture monitors
1729 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1730
Michael Wright3dd60e22019-03-27 22:06:44 +00001731 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1732 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001733 "(%d, %d) in display %" PRId32 ".",
1734 x, y, displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00001735 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1736 goto Failed;
1737 }
1738
1739 if (newTouchedWindowHandle != nullptr) {
1740 // Set target flags.
1741 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1742 if (isSplit) {
1743 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001744 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001745 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1746 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1747 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1748 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1749 }
1750
1751 // Update hover state.
1752 if (isHoverAction) {
1753 newHoverWindowHandle = newTouchedWindowHandle;
1754 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1755 newHoverWindowHandle = mLastHoverWindowHandle;
1756 }
1757
1758 // Update the temporary touch state.
1759 BitSet32 pointerIds;
1760 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001761 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001762 pointerIds.markBit(pointerId);
1763 }
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001764 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001765 }
1766
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001767 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001768 } else {
1769 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1770
1771 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001772 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001773 if (DEBUG_FOCUS) {
1774 ALOGD("Dropping event because the pointer is not down or we previously "
1775 "dropped the pointer down event in display %" PRId32,
1776 displayId);
1777 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001778 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1779 goto Failed;
1780 }
1781
1782 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001783 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001784 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001785 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1786 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001787
1788 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001789 tempTouchState.getFirstForegroundWindowHandle();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001790 sp<InputWindowHandle> newTouchedWindowHandle =
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001791 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001792 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1793 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001794 if (DEBUG_FOCUS) {
1795 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1796 oldTouchedWindowHandle->getName().c_str(),
1797 newTouchedWindowHandle->getName().c_str(), displayId);
1798 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001799 // Make a slippery exit from the old window.
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001800 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1801 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1802 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001803
1804 // Make a slippery entrance into the new window.
1805 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1806 isSplit = true;
1807 }
1808
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001809 int32_t targetFlags =
1810 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001811 if (isSplit) {
1812 targetFlags |= InputTarget::FLAG_SPLIT;
1813 }
1814 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1815 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1816 }
1817
1818 BitSet32 pointerIds;
1819 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001820 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001821 }
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001822 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001823 }
1824 }
1825 }
1826
1827 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1828 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001829 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001830#if DEBUG_HOVER
1831 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001832 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001833#endif
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001834 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1835 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001836 }
1837
1838 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001839 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001840#if DEBUG_HOVER
1841 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001842 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001843#endif
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001844 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1845 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1846 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001847 }
1848 }
1849
1850 // Check permission to inject into all touched foreground windows and ensure there
1851 // is at least one touched foreground window.
1852 {
1853 bool haveForegroundWindow = false;
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001854 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001855 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1856 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001857 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001858 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1859 injectionPermission = INJECTION_PERMISSION_DENIED;
1860 goto Failed;
1861 }
1862 }
1863 }
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001864 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00001865 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakoue0fb6bd2020-04-13 11:40:37 -07001866 ALOGI("Dropping event because there is no touched foreground window in display "
1867 "%" PRId32 " or gesture monitor to receive it.",
1868 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001869 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1870 goto Failed;
1871 }
1872
1873 // Permission granted to injection into all touched foreground windows.
1874 injectionPermission = INJECTION_PERMISSION_GRANTED;
1875 }
1876
1877 // Check whether windows listening for outside touches are owned by the same UID. If it is
1878 // set the policy flag that we will not reveal coordinate information to this window.
1879 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1880 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001881 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001882 if (foregroundWindowHandle) {
1883 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001884 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001885 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1886 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1887 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001888 tempTouchState.addOrUpdateWindow(inputWindowHandle,
1889 InputTarget::FLAG_ZERO_COORDS,
1890 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001891 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001892 }
1893 }
1894 }
1895 }
1896
Michael Wrightd02c5b62014-02-10 15:10:22 -08001897 // If this is the first pointer going down and the touched window has a wallpaper
1898 // then also add the touched wallpaper windows so they are locked in for the duration
1899 // of the touch gesture.
1900 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1901 // engine only supports touch events. We would need to add a mechanism similar
1902 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1903 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1904 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001905 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001906 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001907 const std::vector<sp<InputWindowHandle>> windowHandles =
1908 getWindowHandlesLocked(displayId);
1909 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001910 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001911 if (info->displayId == displayId &&
1912 windowHandle->getInfo()->layoutParamsType == InputWindowInfo::TYPE_WALLPAPER) {
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001913 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001914 .addOrUpdateWindow(windowHandle,
1915 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1916 InputTarget::
1917 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1918 InputTarget::FLAG_DISPATCH_AS_IS,
1919 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920 }
1921 }
1922 }
1923 }
1924
1925 // Success! Output targets.
1926 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1927
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001928 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001929 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001930 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001931 }
1932
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001933 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001934 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001935 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00001936 }
1937
Michael Wrightd02c5b62014-02-10 15:10:22 -08001938 // Drop the outside or hover touch windows since we will not care about them
1939 // in the next iteration.
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001940 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001941
1942Failed:
1943 // Check injection permission once and for all.
1944 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001945 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001946 injectionPermission = INJECTION_PERMISSION_GRANTED;
1947 } else {
1948 injectionPermission = INJECTION_PERMISSION_DENIED;
1949 }
1950 }
1951
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07001952 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
1953 return injectionResult;
1954 }
1955
Michael Wrightd02c5b62014-02-10 15:10:22 -08001956 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07001957 if (!wrongDevice) {
1958 if (switchedDevice) {
1959 if (DEBUG_FOCUS) {
1960 ALOGD("Conflicting pointer actions: Switched to a different device.");
1961 }
1962 *outConflictingPointerActions = true;
1963 }
1964
1965 if (isHoverAction) {
1966 // Started hovering, therefore no longer down.
1967 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001968 if (DEBUG_FOCUS) {
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07001969 ALOGD("Conflicting pointer actions: Hover received while pointer was "
1970 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001971 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001972 *outConflictingPointerActions = true;
1973 }
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001974 tempTouchState.reset();
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07001975 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1976 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001977 tempTouchState.deviceId = entry.deviceId;
1978 tempTouchState.source = entry.source;
1979 tempTouchState.displayId = displayId;
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07001980 }
1981 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
1982 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1983 // All pointers up or canceled.
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001984 tempTouchState.reset();
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07001985 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1986 // First pointer went down.
1987 if (oldState && oldState->down) {
1988 if (DEBUG_FOCUS) {
1989 ALOGD("Conflicting pointer actions: Down received while already down.");
1990 }
1991 *outConflictingPointerActions = true;
1992 }
1993 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1994 // One pointer went up.
1995 if (isSplit) {
1996 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1997 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001998
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07001999 for (size_t i = 0; i < tempTouchState.windows.size();) {
2000 TouchedWindow& touchedWindow = tempTouchState.windows[i];
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07002001 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2002 touchedWindow.pointerIds.clearBit(pointerId);
2003 if (touchedWindow.pointerIds.isEmpty()) {
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07002004 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07002005 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002006 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002007 }
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07002008 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002009 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002010 }
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07002011 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002012
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07002013 // Save changes unless the action was scroll in which case the temporary touch
2014 // state was only valid for this one action.
2015 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
Siarhei Vishniakou1ea3cf12020-03-24 19:50:03 -07002016 if (tempTouchState.displayId >= 0) {
2017 mTouchStatesByDisplay[displayId] = tempTouchState;
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07002018 } else {
2019 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002020 }
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07002021 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002022
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07002023 // Update hover state.
2024 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002025 }
2026
Michael Wrightd02c5b62014-02-10 15:10:22 -08002027 return injectionResult;
2028}
2029
2030void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002031 int32_t targetFlags, BitSet32 pointerIds,
2032 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002033 std::vector<InputTarget>::iterator it =
2034 std::find_if(inputTargets.begin(), inputTargets.end(),
2035 [&windowHandle](const InputTarget& inputTarget) {
2036 return inputTarget.inputChannel->getConnectionToken() ==
2037 windowHandle->getToken();
2038 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002039
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002040 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002041
2042 if (it == inputTargets.end()) {
2043 InputTarget inputTarget;
2044 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
2045 if (inputChannel == nullptr) {
2046 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2047 return;
2048 }
2049 inputTarget.inputChannel = inputChannel;
2050 inputTarget.flags = targetFlags;
2051 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2052 inputTargets.push_back(inputTarget);
2053 it = inputTargets.end() - 1;
2054 }
2055
2056 ALOG_ASSERT(it->flags == targetFlags);
2057 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2058
2059 it->addPointers(pointerIds, -windowInfo->frameLeft, -windowInfo->frameTop,
2060 windowInfo->windowXScale, windowInfo->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002061}
2062
Michael Wright3dd60e22019-03-27 22:06:44 +00002063void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002064 int32_t displayId, float xOffset,
2065 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002066 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2067 mGlobalMonitorsByDisplay.find(displayId);
2068
2069 if (it != mGlobalMonitorsByDisplay.end()) {
2070 const std::vector<Monitor>& monitors = it->second;
2071 for (const Monitor& monitor : monitors) {
2072 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002073 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002074 }
2075}
2076
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002077void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2078 float yOffset,
2079 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002080 InputTarget target;
2081 target.inputChannel = monitor.inputChannel;
2082 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002083 target.setDefaultPointerInfo(xOffset, yOffset, 1 /* windowXScale */, 1 /* windowYScale */);
Michael Wright3dd60e22019-03-27 22:06:44 +00002084 inputTargets.push_back(target);
2085}
2086
Michael Wrightd02c5b62014-02-10 15:10:22 -08002087bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002088 const InjectionState* injectionState) {
2089 if (injectionState &&
2090 (windowHandle == nullptr ||
2091 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2092 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002093 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002094 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002095 "owned by uid %d",
2096 injectionState->injectorPid, injectionState->injectorUid,
2097 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002098 } else {
2099 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002100 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002101 }
2102 return false;
2103 }
2104 return true;
2105}
2106
Robert Carr9cada032020-04-13 17:21:08 -07002107/**
2108 * Indicate whether one window handle should be considered as obscuring
2109 * another window handle. We only check a few preconditions. Actually
2110 * checking the bounds is left to the caller.
2111 */
2112static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2113 const sp<InputWindowHandle>& otherHandle) {
2114 // Compare by token so cloned layers aren't counted
2115 if (haveSameToken(windowHandle, otherHandle)) {
2116 return false;
2117 }
2118 auto info = windowHandle->getInfo();
2119 auto otherInfo = otherHandle->getInfo();
2120 if (!otherInfo->visible) {
2121 return false;
Robert Carr98c34a82020-06-09 15:36:34 -07002122 } else if (info->ownerPid == otherInfo->ownerPid) {
2123 // If ownerPid is the same we don't generate occlusion events as there
2124 // is no in-process security boundary.
Robert Carr9cada032020-04-13 17:21:08 -07002125 return false;
2126 } else if (otherInfo->isTrustedOverlay()) {
2127 return false;
2128 } else if (otherInfo->displayId != info->displayId) {
2129 return false;
2130 }
2131 return true;
2132}
2133
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002134bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2135 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002136 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002137 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
2138 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carr9cada032020-04-13 17:21:08 -07002139 if (windowHandle == otherHandle) {
2140 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002141 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002142 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carr9cada032020-04-13 17:21:08 -07002143 if (canBeObscuredBy(windowHandle, otherHandle) &&
2144 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002145 return true;
2146 }
2147 }
2148 return false;
2149}
2150
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002151bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2152 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002153 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002154 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002155 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carr9cada032020-04-13 17:21:08 -07002156 if (windowHandle == otherHandle) {
2157 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002158 }
2159
2160 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carr9cada032020-04-13 17:21:08 -07002161 if (canBeObscuredBy(windowHandle, otherHandle) &&
2162 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002163 return true;
2164 }
2165 }
2166 return false;
2167}
2168
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002169std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002170 const sp<InputApplicationHandle>& applicationHandle,
2171 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002172 if (applicationHandle != nullptr) {
2173 if (windowHandle != nullptr) {
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -07002174 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002175 } else {
2176 return applicationHandle->getName();
2177 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002178 } else if (windowHandle != nullptr) {
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -07002179 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002180 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002181 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002182 }
2183}
2184
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002185void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002186 if (eventEntry.type == EventEntry::Type::FOCUS) {
2187 // Focus events are passed to apps, but do not represent user activity.
2188 return;
2189 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002190 int32_t displayId = getTargetDisplayId(eventEntry);
2191 sp<InputWindowHandle> focusedWindowHandle =
2192 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
2193 if (focusedWindowHandle != nullptr) {
2194 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002195 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
2196#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002197 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002198#endif
2199 return;
2200 }
2201 }
2202
2203 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002204 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002205 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002206 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2207 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002208 return;
2209 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002210
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002211 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002212 eventType = USER_ACTIVITY_EVENT_TOUCH;
2213 }
2214 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002215 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002216 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002217 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2218 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002219 return;
2220 }
2221 eventType = USER_ACTIVITY_EVENT_BUTTON;
2222 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002223 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002224 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002225 case EventEntry::Type::CONFIGURATION_CHANGED:
2226 case EventEntry::Type::DEVICE_RESET: {
2227 LOG_ALWAYS_FATAL("%s events are not user activity",
2228 EventEntry::typeToString(eventEntry.type));
2229 break;
2230 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002231 }
2232
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002233 std::unique_ptr<CommandEntry> commandEntry =
2234 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002235 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002236 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002237 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002238}
2239
2240void InputDispatcher::prepareDispatchCycleLocked(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 =
Garfield Tan1c7bc862020-01-28 13:24:04 -08002246 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tanc51d1ba2020-01-28 13:24:04 -08002247 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002248 ATRACE_NAME(message.c_str());
2249 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002250#if DEBUG_DISPATCH_CYCLE
2251 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002252 "globalScaleFactor=%f, pointerIds=0x%x %s",
2253 connection->getInputChannelName().c_str(), inputTarget.flags,
2254 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2255 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002256#endif
2257
2258 // Skip this event if the connection status is not normal.
2259 // We don't want to enqueue additional outbound events if the connection is broken.
2260 if (connection->status != Connection::STATUS_NORMAL) {
2261#if DEBUG_DISPATCH_CYCLE
2262 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002263 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002264#endif
2265 return;
2266 }
2267
2268 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002269 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2270 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2271 "Entry type %s should not have FLAG_SPLIT",
2272 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002273
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002274 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002275 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002276 MotionEntry* splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002277 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002278 if (!splitMotionEntry) {
2279 return; // split event was dropped
2280 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002281 if (DEBUG_FOCUS) {
2282 ALOGD("channel '%s' ~ Split motion event.",
2283 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002284 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002285 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002286 enqueueDispatchEntriesLocked(currentTime, connection, splitMotionEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002287 splitMotionEntry->release();
2288 return;
2289 }
2290 }
2291
2292 // Not splitting. Enqueue dispatch entries for the event as is.
2293 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2294}
2295
2296void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002297 const sp<Connection>& connection,
2298 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002299 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002300 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002301 std::string message =
Garfield Tan1c7bc862020-01-28 13:24:04 -08002302 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tanc51d1ba2020-01-28 13:24:04 -08002303 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002304 ATRACE_NAME(message.c_str());
2305 }
2306
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002307 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002308
2309 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002310 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002311 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002312 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002313 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002314 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002315 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002316 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002317 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002318 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002319 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002320 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002321 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002322
2323 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002324 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002325 startDispatchCycleLocked(currentTime, connection);
2326 }
2327}
2328
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002329void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
2330 EventEntry* eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002331 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002332 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002333 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002334 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2335 connection->getInputChannelName().c_str(),
2336 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002337 ATRACE_NAME(message.c_str());
2338 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002339 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002340 if (!(inputTargetFlags & dispatchMode)) {
2341 return;
2342 }
2343 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2344
2345 // This is a new event.
2346 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002347 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002348 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002349
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002350 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2351 // different EventEntry than what was passed in.
2352 EventEntry* newEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002353 // Apply target flags and update the connection's input state.
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002354 switch (newEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002355 case EventEntry::Type::KEY: {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002356 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*newEntry);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002357 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002358 dispatchEntry->resolvedAction = keyEntry.action;
2359 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002360
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002361 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2362 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002363#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002364 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2365 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002366#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002367 return; // skip the inconsistent event
2368 }
2369 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002370 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002371
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002372 case EventEntry::Type::MOTION: {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002373 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*newEntry);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002374 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2375 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2376 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2377 static_cast<int32_t>(IdGenerator::Source::OTHER);
2378 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002379 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2380 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2381 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2382 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2383 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2384 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2385 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2386 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2387 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2388 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2389 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002390 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002391 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002392 }
2393 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002394 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2395 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002396#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002397 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2398 "event",
2399 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002400#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002401 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2402 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002403
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002404 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002405 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2406 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2407 }
2408 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2409 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2410 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002411
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002412 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2413 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002414#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002415 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2416 "event",
2417 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002418#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002419 return; // skip the inconsistent event
2420 }
2421
Garfield Tan1c7bc862020-01-28 13:24:04 -08002422 dispatchEntry->resolvedEventId =
2423 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2424 ? mIdGenerator.nextId()
2425 : motionEntry.id;
2426 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2427 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2428 ") to MotionEvent(id=0x%" PRIx32 ").",
2429 motionEntry.id, dispatchEntry->resolvedEventId);
2430 ATRACE_NAME(message.c_str());
2431 }
2432
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002433 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002434 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002435
2436 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002437 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002438 case EventEntry::Type::FOCUS: {
2439 break;
2440 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002441 case EventEntry::Type::CONFIGURATION_CHANGED:
2442 case EventEntry::Type::DEVICE_RESET: {
2443 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002444 EventEntry::typeToString(newEntry->type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002445 break;
2446 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002447 }
2448
2449 // Remember that we are waiting for this dispatch to complete.
2450 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002451 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002452 }
2453
2454 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002455 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002456 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002457}
2458
chaviwfd6d3512019-03-25 13:23:49 -07002459void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002460 const sp<IBinder>& newToken) {
chaviw8c9cf542019-03-25 13:02:48 -07002461 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002462 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2463 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002464 return;
2465 }
2466
2467 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2468 if (inputWindowHandle == nullptr) {
2469 return;
2470 }
2471
chaviw8c9cf542019-03-25 13:02:48 -07002472 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002473 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002474
2475 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2476
2477 if (!hasFocusChanged) {
2478 return;
2479 }
2480
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002481 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2482 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002483 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002484 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002485}
2486
2487void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002488 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002489 if (ATRACE_ENABLED()) {
2490 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002491 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002492 ATRACE_NAME(message.c_str());
2493 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002494#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002495 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002496#endif
2497
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002498 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2499 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002500 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07002501 const nsecs_t timeout =
2502 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
2503 dispatchEntry->timeoutTime = currentTime + timeout;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002504
2505 // Publish the event.
2506 status_t status;
2507 EventEntry* eventEntry = dispatchEntry->eventEntry;
2508 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002509 case EventEntry::Type::KEY: {
Edgar Arriaga3d61bc12020-04-16 18:46:48 -07002510 const KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2511 std::array<uint8_t, 32> hmac = getSignature(*keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002512
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002513 // Publish the key event.
Garfield Tan1c7bc862020-01-28 13:24:04 -08002514 status =
2515 connection->inputPublisher
2516 .publishKeyEvent(dispatchEntry->seq, dispatchEntry->resolvedEventId,
2517 keyEntry->deviceId, keyEntry->source,
2518 keyEntry->displayId, std::move(hmac),
2519 dispatchEntry->resolvedAction,
2520 dispatchEntry->resolvedFlags, keyEntry->keyCode,
2521 keyEntry->scanCode, keyEntry->metaState,
2522 keyEntry->repeatCount, keyEntry->downTime,
2523 keyEntry->eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002524 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002525 }
2526
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002527 case EventEntry::Type::MOTION: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002528 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002529
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002530 PointerCoords scaledCoords[MAX_POINTERS];
2531 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2532
chaviw82357092020-01-28 13:13:06 -08002533 // Set the X and Y offset and X and Y scale depending on the input source.
2534 float xOffset = 0.0f, yOffset = 0.0f;
2535 float xScale = 1.0f, yScale = 1.0f;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002536 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
2537 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2538 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002539 xScale = dispatchEntry->windowXScale;
2540 yScale = dispatchEntry->windowYScale;
2541 xOffset = dispatchEntry->xOffset * xScale;
2542 yOffset = dispatchEntry->yOffset * yScale;
2543 if (globalScaleFactor != 1.0f) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002544 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2545 scaledCoords[i] = motionEntry->pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002546 // Don't apply window scale here since we don't want scale to affect raw
2547 // coordinates. The scale will be sent back to the client and applied
2548 // later when requesting relative coordinates.
2549 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2550 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002551 }
2552 usingCoords = scaledCoords;
2553 }
2554 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002555 // We don't want the dispatch target to know.
2556 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
2557 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2558 scaledCoords[i].clear();
2559 }
2560 usingCoords = scaledCoords;
2561 }
2562 }
Edgar Arriaga3d61bc12020-04-16 18:46:48 -07002563
2564 std::array<uint8_t, 32> hmac = getSignature(*motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002565
2566 // Publish the motion event.
2567 status = connection->inputPublisher
Garfield Tan1c7bc862020-01-28 13:24:04 -08002568 .publishMotionEvent(dispatchEntry->seq,
2569 dispatchEntry->resolvedEventId,
2570 motionEntry->deviceId, motionEntry->source,
2571 motionEntry->displayId, std::move(hmac),
2572 dispatchEntry->resolvedAction,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002573 motionEntry->actionButton,
2574 dispatchEntry->resolvedFlags,
2575 motionEntry->edgeFlags, motionEntry->metaState,
2576 motionEntry->buttonState,
chaviw82357092020-01-28 13:13:06 -08002577 motionEntry->classification, xScale, yScale,
2578 xOffset, yOffset, motionEntry->xPrecision,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002579 motionEntry->yPrecision,
2580 motionEntry->xCursorPosition,
2581 motionEntry->yCursorPosition,
2582 motionEntry->downTime, motionEntry->eventTime,
2583 motionEntry->pointerCount,
2584 motionEntry->pointerProperties, usingCoords);
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05002585 reportTouchEventForStatistics(*motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002586 break;
2587 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002588 case EventEntry::Type::FOCUS: {
2589 FocusEntry* focusEntry = static_cast<FocusEntry*>(eventEntry);
2590 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Garfield Tan1c7bc862020-01-28 13:24:04 -08002591 focusEntry->id,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002592 focusEntry->hasFocus,
2593 mInTouchMode);
2594 break;
2595 }
2596
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002597 case EventEntry::Type::CONFIGURATION_CHANGED:
2598 case EventEntry::Type::DEVICE_RESET: {
2599 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
2600 EventEntry::typeToString(eventEntry->type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002601 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002602 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002603 }
2604
2605 // Check the result.
2606 if (status) {
2607 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002608 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002609 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002610 "This is unexpected because the wait queue is empty, so the pipe "
2611 "should be empty and we shouldn't have any problems writing an "
2612 "event to it, status=%d",
2613 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002614 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2615 } else {
2616 // Pipe is full and we are waiting for the app to finish process some events
2617 // before sending more events to it.
2618#if DEBUG_DISPATCH_CYCLE
2619 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002620 "waiting for the application to catch up",
2621 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002622#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08002623 }
2624 } else {
2625 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002626 "status=%d",
2627 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002628 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2629 }
2630 return;
2631 }
2632
2633 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002634 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2635 connection->outboundQueue.end(),
2636 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002637 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002638 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07002639 if (connection->responsive) {
2640 mAnrTracker.insert(dispatchEntry->timeoutTime,
2641 connection->inputChannel->getConnectionToken());
2642 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002643 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002644 }
2645}
2646
Edgar Arriaga3d61bc12020-04-16 18:46:48 -07002647const std::array<uint8_t, 32> InputDispatcher::getSignature(
2648 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
2649 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
2650 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
2651 // Only sign events up and down events as the purely move events
2652 // are tied to their up/down counterparts so signing would be redundant.
2653 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
2654 verifiedEvent.actionMasked = actionMasked;
2655 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
2656 return mHmacKeyManager.sign(verifiedEvent);
2657 }
2658 return INVALID_HMAC;
2659}
2660
2661const std::array<uint8_t, 32> InputDispatcher::getSignature(
2662 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
2663 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
2664 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
2665 verifiedEvent.action = dispatchEntry.resolvedAction;
2666 return mHmacKeyManager.sign(verifiedEvent);
2667}
2668
Michael Wrightd02c5b62014-02-10 15:10:22 -08002669void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002670 const sp<Connection>& connection, uint32_t seq,
2671 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002672#if DEBUG_DISPATCH_CYCLE
2673 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002674 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002675#endif
2676
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002677 if (connection->status == Connection::STATUS_BROKEN ||
2678 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002679 return;
2680 }
2681
2682 // Notify other system components and prepare to start the next dispatch cycle.
2683 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2684}
2685
2686void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002687 const sp<Connection>& connection,
2688 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002689#if DEBUG_DISPATCH_CYCLE
2690 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002691 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002692#endif
2693
2694 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002695 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002696 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002697 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002698 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002699
2700 // The connection appears to be unrecoverably broken.
2701 // Ignore already broken or zombie connections.
2702 if (connection->status == Connection::STATUS_NORMAL) {
2703 connection->status = Connection::STATUS_BROKEN;
2704
2705 if (notify) {
2706 // Notify other system components.
2707 onDispatchCycleBrokenLocked(currentTime, connection);
2708 }
2709 }
2710}
2711
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002712void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2713 while (!queue.empty()) {
2714 DispatchEntry* dispatchEntry = queue.front();
2715 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002716 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002717 }
2718}
2719
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002720void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002721 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002722 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002723 }
2724 delete dispatchEntry;
2725}
2726
2727int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2728 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2729
2730 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002731 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002732
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002733 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002734 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002735 "fd=%d, events=0x%x",
2736 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002737 return 0; // remove the callback
2738 }
2739
2740 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002741 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002742 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2743 if (!(events & ALOOPER_EVENT_INPUT)) {
2744 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002745 "events=0x%x",
2746 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002747 return 1;
2748 }
2749
2750 nsecs_t currentTime = now();
2751 bool gotOne = false;
2752 status_t status;
2753 for (;;) {
2754 uint32_t seq;
2755 bool handled;
2756 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2757 if (status) {
2758 break;
2759 }
2760 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2761 gotOne = true;
2762 }
2763 if (gotOne) {
2764 d->runCommandsLockedInterruptible();
2765 if (status == WOULD_BLOCK) {
2766 return 1;
2767 }
2768 }
2769
2770 notify = status != DEAD_OBJECT || !connection->monitor;
2771 if (notify) {
2772 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002773 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002774 }
2775 } else {
2776 // Monitor channels are never explicitly unregistered.
2777 // We do it automatically when the remote endpoint is closed so don't warn
2778 // about them.
arthurhungd352cb32020-04-28 17:09:28 +08002779 const bool stillHaveWindowHandle =
2780 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
2781 nullptr;
2782 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002783 if (notify) {
2784 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002785 "events=0x%x",
2786 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002787 }
2788 }
2789
2790 // Unregister the channel.
2791 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2792 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002793 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08002794}
2795
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002796void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002797 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002798 for (const auto& pair : mConnectionsByFd) {
2799 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002800 }
2801}
2802
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002803void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002804 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002805 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2806 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2807}
2808
2809void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2810 const CancelationOptions& options,
2811 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2812 for (const auto& it : monitorsByDisplay) {
2813 const std::vector<Monitor>& monitors = it.second;
2814 for (const Monitor& monitor : monitors) {
2815 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002816 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002817 }
2818}
2819
Michael Wrightd02c5b62014-02-10 15:10:22 -08002820void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2821 const sp<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002822 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002823 if (connection == nullptr) {
2824 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002825 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002826
2827 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002828}
2829
2830void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2831 const sp<Connection>& connection, const CancelationOptions& options) {
2832 if (connection->status == Connection::STATUS_BROKEN) {
2833 return;
2834 }
2835
2836 nsecs_t currentTime = now();
2837
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07002838 std::vector<EventEntry*> cancelationEvents =
2839 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002840
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002841 if (cancelationEvents.empty()) {
2842 return;
2843 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002844#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002845 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
2846 "with reality: %s, mode=%d.",
2847 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
2848 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002849#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08002850
2851 InputTarget target;
2852 sp<InputWindowHandle> windowHandle =
2853 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
2854 if (windowHandle != nullptr) {
2855 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2856 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2857 windowInfo->windowXScale, windowInfo->windowYScale);
2858 target.globalScaleFactor = windowInfo->globalScaleFactor;
2859 }
2860 target.inputChannel = connection->inputChannel;
2861 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2862
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002863 for (size_t i = 0; i < cancelationEvents.size(); i++) {
2864 EventEntry* cancelationEventEntry = cancelationEvents[i];
2865 switch (cancelationEventEntry->type) {
2866 case EventEntry::Type::KEY: {
2867 logOutboundKeyDetails("cancel - ",
2868 static_cast<const KeyEntry&>(*cancelationEventEntry));
2869 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002870 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002871 case EventEntry::Type::MOTION: {
2872 logOutboundMotionDetails("cancel - ",
2873 static_cast<const MotionEntry&>(*cancelationEventEntry));
2874 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002875 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002876 case EventEntry::Type::FOCUS: {
2877 LOG_ALWAYS_FATAL("Canceling focus events is not supported");
2878 break;
2879 }
2880 case EventEntry::Type::CONFIGURATION_CHANGED:
2881 case EventEntry::Type::DEVICE_RESET: {
2882 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2883 EventEntry::typeToString(cancelationEventEntry->type));
2884 break;
2885 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002886 }
2887
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002888 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
2889 target, InputTarget::FLAG_DISPATCH_AS_IS);
2890
2891 cancelationEventEntry->release();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002892 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08002893
2894 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002895}
2896
Svet Ganov5d3bc372020-01-26 23:11:07 -08002897void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
2898 const sp<Connection>& connection) {
2899 if (connection->status == Connection::STATUS_BROKEN) {
2900 return;
2901 }
2902
2903 nsecs_t currentTime = now();
2904
2905 std::vector<EventEntry*> downEvents =
2906 connection->inputState.synthesizePointerDownEvents(currentTime);
2907
2908 if (downEvents.empty()) {
2909 return;
2910 }
2911
2912#if DEBUG_OUTBOUND_EVENT_DETAILS
2913 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
2914 connection->getInputChannelName().c_str(), downEvents.size());
2915#endif
2916
2917 InputTarget target;
2918 sp<InputWindowHandle> windowHandle =
2919 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
2920 if (windowHandle != nullptr) {
2921 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2922 target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
2923 windowInfo->windowXScale, windowInfo->windowYScale);
2924 target.globalScaleFactor = windowInfo->globalScaleFactor;
2925 }
2926 target.inputChannel = connection->inputChannel;
2927 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2928
2929 for (EventEntry* downEventEntry : downEvents) {
2930 switch (downEventEntry->type) {
2931 case EventEntry::Type::MOTION: {
2932 logOutboundMotionDetails("down - ",
2933 static_cast<const MotionEntry&>(*downEventEntry));
2934 break;
2935 }
2936
2937 case EventEntry::Type::KEY:
2938 case EventEntry::Type::FOCUS:
2939 case EventEntry::Type::CONFIGURATION_CHANGED:
2940 case EventEntry::Type::DEVICE_RESET: {
2941 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
2942 EventEntry::typeToString(downEventEntry->type));
2943 break;
2944 }
2945 }
2946
2947 enqueueDispatchEntryLocked(connection, downEventEntry, // increments ref
2948 target, InputTarget::FLAG_DISPATCH_AS_IS);
2949
2950 downEventEntry->release();
2951 }
2952
2953 startDispatchCycleLocked(currentTime, connection);
2954}
2955
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002956MotionEntry* InputDispatcher::splitMotionEvent(const MotionEntry& originalMotionEntry,
Garfield Tane84e6f92019-08-29 17:28:41 -07002957 BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002958 ALOG_ASSERT(pointerIds.value != 0);
2959
2960 uint32_t splitPointerIndexMap[MAX_POINTERS];
2961 PointerProperties splitPointerProperties[MAX_POINTERS];
2962 PointerCoords splitPointerCoords[MAX_POINTERS];
2963
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002964 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002965 uint32_t splitPointerCount = 0;
2966
2967 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002968 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002969 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002970 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002971 uint32_t pointerId = uint32_t(pointerProperties.id);
2972 if (pointerIds.hasBit(pointerId)) {
2973 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2974 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2975 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002976 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002977 splitPointerCount += 1;
2978 }
2979 }
2980
2981 if (splitPointerCount != pointerIds.count()) {
2982 // This is bad. We are missing some of the pointers that we expected to deliver.
2983 // Most likely this indicates that we received an ACTION_MOVE events that has
2984 // different pointer ids than we expected based on the previous ACTION_DOWN
2985 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2986 // in this way.
2987 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002988 "we expected there to be %d pointers. This probably means we received "
2989 "a broken sequence of pointer ids from the input device.",
2990 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002991 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002992 }
2993
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002994 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002995 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002996 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
2997 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002998 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2999 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003000 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003001 uint32_t pointerId = uint32_t(pointerProperties.id);
3002 if (pointerIds.hasBit(pointerId)) {
3003 if (pointerIds.count() == 1) {
3004 // The first/last pointer went down/up.
3005 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003006 ? AMOTION_EVENT_ACTION_DOWN
3007 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003008 } else {
3009 // A secondary pointer went down/up.
3010 uint32_t splitPointerIndex = 0;
3011 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3012 splitPointerIndex += 1;
3013 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003014 action = maskedAction |
3015 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003016 }
3017 } else {
3018 // An unrelated pointer changed.
3019 action = AMOTION_EVENT_ACTION_MOVE;
3020 }
3021 }
3022
Garfield Tan1c7bc862020-01-28 13:24:04 -08003023 int32_t newId = mIdGenerator.nextId();
3024 if (ATRACE_ENABLED()) {
3025 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3026 ") to MotionEvent(id=0x%" PRIx32 ").",
3027 originalMotionEntry.id, newId);
3028 ATRACE_NAME(message.c_str());
3029 }
Garfield Tan00f511d2019-06-12 16:55:40 -07003030 MotionEntry* splitMotionEntry =
Garfield Tan1c7bc862020-01-28 13:24:04 -08003031 new MotionEntry(newId, originalMotionEntry.eventTime, originalMotionEntry.deviceId,
3032 originalMotionEntry.source, originalMotionEntry.displayId,
3033 originalMotionEntry.policyFlags, action,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003034 originalMotionEntry.actionButton, originalMotionEntry.flags,
3035 originalMotionEntry.metaState, originalMotionEntry.buttonState,
3036 originalMotionEntry.classification, originalMotionEntry.edgeFlags,
3037 originalMotionEntry.xPrecision, originalMotionEntry.yPrecision,
3038 originalMotionEntry.xCursorPosition,
3039 originalMotionEntry.yCursorPosition, originalMotionEntry.downTime,
Garfield Tan00f511d2019-06-12 16:55:40 -07003040 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003041
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003042 if (originalMotionEntry.injectionState) {
3043 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003044 splitMotionEntry->injectionState->refCount += 1;
3045 }
3046
3047 return splitMotionEntry;
3048}
3049
3050void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3051#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003052 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003053#endif
3054
3055 bool needWake;
3056 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003057 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003058
Prabir Pradhan42611e02018-11-27 14:04:02 -08003059 ConfigurationChangedEntry* newEntry =
Garfield Tanc51d1ba2020-01-28 13:24:04 -08003060 new ConfigurationChangedEntry(args->id, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003061 needWake = enqueueInboundEventLocked(newEntry);
3062 } // release lock
3063
3064 if (needWake) {
3065 mLooper->wake();
3066 }
3067}
3068
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003069/**
3070 * If one of the meta shortcuts is detected, process them here:
3071 * Meta + Backspace -> generate BACK
3072 * Meta + Enter -> generate HOME
3073 * This will potentially overwrite keyCode and metaState.
3074 */
3075void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003076 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003077 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3078 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3079 if (keyCode == AKEYCODE_DEL) {
3080 newKeyCode = AKEYCODE_BACK;
3081 } else if (keyCode == AKEYCODE_ENTER) {
3082 newKeyCode = AKEYCODE_HOME;
3083 }
3084 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003085 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003086 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07003087 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003088 keyCode = newKeyCode;
3089 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3090 }
3091 } else if (action == AKEY_EVENT_ACTION_UP) {
3092 // In order to maintain a consistent stream of up and down events, check to see if the key
3093 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3094 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003095 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003096 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07003097 auto replacementIt = mReplacedKeys.find(replacement);
3098 if (replacementIt != mReplacedKeys.end()) {
3099 keyCode = replacementIt->second;
3100 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003101 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3102 }
3103 }
3104}
3105
Michael Wrightd02c5b62014-02-10 15:10:22 -08003106void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3107#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003108 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3109 "policyFlags=0x%x, action=0x%x, "
3110 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3111 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3112 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3113 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003114#endif
3115 if (!validateKeyEvent(args->action)) {
3116 return;
3117 }
3118
3119 uint32_t policyFlags = args->policyFlags;
3120 int32_t flags = args->flags;
3121 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003122 // InputDispatcher tracks and generates key repeats on behalf of
3123 // whatever notifies it, so repeatCount should always be set to 0
3124 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003125 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3126 policyFlags |= POLICY_FLAG_VIRTUAL;
3127 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3128 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003129 if (policyFlags & POLICY_FLAG_FUNCTION) {
3130 metaState |= AMETA_FUNCTION_ON;
3131 }
3132
3133 policyFlags |= POLICY_FLAG_TRUSTED;
3134
Michael Wright78f24442014-08-06 15:55:28 -07003135 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003136 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003137
Michael Wrightd02c5b62014-02-10 15:10:22 -08003138 KeyEvent event;
Garfield Tanc51d1ba2020-01-28 13:24:04 -08003139 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tanfbe732e2020-01-24 11:26:14 -08003140 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3141 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003142
Michael Wright2b3c3302018-03-02 17:19:13 +00003143 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003144 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003145 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3146 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003147 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003148 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003149
Michael Wrightd02c5b62014-02-10 15:10:22 -08003150 bool needWake;
3151 { // acquire lock
3152 mLock.lock();
3153
3154 if (shouldSendKeyToInputFilterLocked(args)) {
3155 mLock.unlock();
3156
3157 policyFlags |= POLICY_FLAG_FILTERED;
3158 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3159 return; // event was consumed by the filter
3160 }
3161
3162 mLock.lock();
3163 }
3164
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003165 KeyEntry* newEntry =
Garfield Tanc51d1ba2020-01-28 13:24:04 -08003166 new KeyEntry(args->id, args->eventTime, args->deviceId, args->source,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003167 args->displayId, policyFlags, args->action, flags, keyCode,
3168 args->scanCode, metaState, repeatCount, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003169
3170 needWake = enqueueInboundEventLocked(newEntry);
3171 mLock.unlock();
3172 } // release lock
3173
3174 if (needWake) {
3175 mLooper->wake();
3176 }
3177}
3178
3179bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3180 return mInputFilterEnabled;
3181}
3182
3183void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3184#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tanc51d1ba2020-01-28 13:24:04 -08003185 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3186 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003187 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3188 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003189 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tanc51d1ba2020-01-28 13:24:04 -08003190 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3191 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3192 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3193 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003194 for (uint32_t i = 0; i < args->pointerCount; i++) {
3195 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003196 "x=%f, y=%f, pressure=%f, size=%f, "
3197 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3198 "orientation=%f",
3199 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3200 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3201 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3202 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3203 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3204 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3205 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3206 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3207 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3208 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003209 }
3210#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003211 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3212 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003213 return;
3214 }
3215
3216 uint32_t policyFlags = args->policyFlags;
3217 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003218
3219 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003220 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003221 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3222 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003223 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003224 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003225
3226 bool needWake;
3227 { // acquire lock
3228 mLock.lock();
3229
3230 if (shouldSendMotionToInputFilterLocked(args)) {
3231 mLock.unlock();
3232
3233 MotionEvent event;
Garfield Tanc51d1ba2020-01-28 13:24:04 -08003234 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3235 args->action, args->actionButton, args->flags, args->edgeFlags,
3236 args->metaState, args->buttonState, args->classification, 1 /*xScale*/,
3237 1 /*yScale*/, 0 /* xOffset */, 0 /* yOffset */, args->xPrecision,
3238 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3239 args->downTime, args->eventTime, args->pointerCount,
3240 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003241
3242 policyFlags |= POLICY_FLAG_FILTERED;
3243 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3244 return; // event was consumed by the filter
3245 }
3246
3247 mLock.lock();
3248 }
3249
3250 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07003251 MotionEntry* newEntry =
Garfield Tanc51d1ba2020-01-28 13:24:04 -08003252 new MotionEntry(args->id, args->eventTime, args->deviceId, args->source,
Garfield Tan00f511d2019-06-12 16:55:40 -07003253 args->displayId, policyFlags, args->action, args->actionButton,
3254 args->flags, args->metaState, args->buttonState,
3255 args->classification, args->edgeFlags, args->xPrecision,
3256 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
3257 args->downTime, args->pointerCount, args->pointerProperties,
3258 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003259
3260 needWake = enqueueInboundEventLocked(newEntry);
3261 mLock.unlock();
3262 } // release lock
3263
3264 if (needWake) {
3265 mLooper->wake();
3266 }
3267}
3268
3269bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003270 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003271}
3272
3273void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3274#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003275 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003276 "switchMask=0x%08x",
3277 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003278#endif
3279
3280 uint32_t policyFlags = args->policyFlags;
3281 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003282 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003283}
3284
3285void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3286#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003287 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3288 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003289#endif
3290
3291 bool needWake;
3292 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003293 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003294
Prabir Pradhan42611e02018-11-27 14:04:02 -08003295 DeviceResetEntry* newEntry =
Garfield Tanc51d1ba2020-01-28 13:24:04 -08003296 new DeviceResetEntry(args->id, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003297 needWake = enqueueInboundEventLocked(newEntry);
3298 } // release lock
3299
3300 if (needWake) {
3301 mLooper->wake();
3302 }
3303}
3304
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003305int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid,
3306 int32_t injectorUid, int32_t syncMode,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003307 std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003308#if DEBUG_INBOUND_EVENT_DETAILS
3309 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003310 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3311 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003312#endif
3313
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003314 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003315
3316 policyFlags |= POLICY_FLAG_INJECTED;
3317 if (hasInjectionPermission(injectorPid, injectorUid)) {
3318 policyFlags |= POLICY_FLAG_TRUSTED;
3319 }
3320
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003321 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003322 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003323 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003324 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3325 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003326 if (!validateKeyEvent(action)) {
3327 return INPUT_EVENT_INJECTION_FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003328 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003329
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003330 int32_t flags = incomingKey.getFlags();
3331 int32_t keyCode = incomingKey.getKeyCode();
3332 int32_t metaState = incomingKey.getMetaState();
3333 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003334 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003335 KeyEvent keyEvent;
Garfield Tanfbe732e2020-01-24 11:26:14 -08003336 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003337 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3338 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3339 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003340
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003341 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3342 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003343 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003344
3345 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3346 android::base::Timer t;
3347 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3348 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3349 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3350 std::to_string(t.duration().count()).c_str());
3351 }
3352 }
3353
3354 mLock.lock();
3355 KeyEntry* injectedEntry =
Garfield Tanfbe732e2020-01-24 11:26:14 -08003356 new KeyEntry(incomingKey.getId(), incomingKey.getEventTime(),
3357 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
arthurhungb1462ec2020-04-20 17:18:37 +08003358 incomingKey.getDisplayId(), policyFlags, action, flags, keyCode,
3359 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
Garfield Tanfbe732e2020-01-24 11:26:14 -08003360 incomingKey.getDownTime());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003361 injectedEntries.push(injectedEntry);
3362 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003363 }
3364
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003365 case AINPUT_EVENT_TYPE_MOTION: {
3366 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3367 int32_t action = motionEvent->getAction();
3368 size_t pointerCount = motionEvent->getPointerCount();
3369 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3370 int32_t actionButton = motionEvent->getActionButton();
3371 int32_t displayId = motionEvent->getDisplayId();
3372 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
3373 return INPUT_EVENT_INJECTION_FAILED;
3374 }
3375
3376 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3377 nsecs_t eventTime = motionEvent->getEventTime();
3378 android::base::Timer t;
3379 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3380 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3381 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3382 std::to_string(t.duration().count()).c_str());
3383 }
3384 }
3385
3386 mLock.lock();
3387 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3388 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
3389 MotionEntry* injectedEntry =
Garfield Tanfbe732e2020-01-24 11:26:14 -08003390 new MotionEntry(motionEvent->getId(), *sampleEventTimes, VIRTUAL_KEYBOARD_ID,
3391 motionEvent->getSource(), motionEvent->getDisplayId(),
3392 policyFlags, action, actionButton, motionEvent->getFlags(),
3393 motionEvent->getMetaState(), motionEvent->getButtonState(),
3394 motionEvent->getClassification(), motionEvent->getEdgeFlags(),
3395 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
Garfield Tan00f511d2019-06-12 16:55:40 -07003396 motionEvent->getRawXCursorPosition(),
3397 motionEvent->getRawYCursorPosition(),
3398 motionEvent->getDownTime(), uint32_t(pointerCount),
3399 pointerProperties, samplePointerCoords,
3400 motionEvent->getXOffset(), motionEvent->getYOffset());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003401 injectedEntries.push(injectedEntry);
3402 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3403 sampleEventTimes += 1;
3404 samplePointerCoords += pointerCount;
3405 MotionEntry* nextInjectedEntry =
Garfield Tanfbe732e2020-01-24 11:26:14 -08003406 new MotionEntry(motionEvent->getId(), *sampleEventTimes,
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003407 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003408 motionEvent->getDisplayId(), policyFlags, action,
3409 actionButton, motionEvent->getFlags(),
3410 motionEvent->getMetaState(), motionEvent->getButtonState(),
3411 motionEvent->getClassification(),
3412 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3413 motionEvent->getYPrecision(),
3414 motionEvent->getRawXCursorPosition(),
3415 motionEvent->getRawYCursorPosition(),
3416 motionEvent->getDownTime(), uint32_t(pointerCount),
3417 pointerProperties, samplePointerCoords,
3418 motionEvent->getXOffset(), motionEvent->getYOffset());
3419 injectedEntries.push(nextInjectedEntry);
3420 }
3421 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003422 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003423
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003424 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003425 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003426 return INPUT_EVENT_INJECTION_FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003427 }
3428
3429 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3430 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3431 injectionState->injectionIsAsync = true;
3432 }
3433
3434 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003435 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003436
3437 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003438 while (!injectedEntries.empty()) {
3439 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3440 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003441 }
3442
3443 mLock.unlock();
3444
3445 if (needWake) {
3446 mLooper->wake();
3447 }
3448
3449 int32_t injectionResult;
3450 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003451 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003452
3453 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3454 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3455 } else {
3456 for (;;) {
3457 injectionResult = injectionState->injectionResult;
3458 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3459 break;
3460 }
3461
3462 nsecs_t remainingTimeout = endTime - now();
3463 if (remainingTimeout <= 0) {
3464#if DEBUG_INJECTION
3465 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003466 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003467#endif
3468 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3469 break;
3470 }
3471
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003472 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003473 }
3474
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003475 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED &&
3476 syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003477 while (injectionState->pendingForegroundDispatches != 0) {
3478#if DEBUG_INJECTION
3479 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003480 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003481#endif
3482 nsecs_t remainingTimeout = endTime - now();
3483 if (remainingTimeout <= 0) {
3484#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003485 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3486 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003487#endif
3488 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3489 break;
3490 }
3491
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003492 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003493 }
3494 }
3495 }
3496
3497 injectionState->release();
3498 } // release lock
3499
3500#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003501 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003502 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003503#endif
3504
3505 return injectionResult;
3506}
3507
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003508std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05003509 std::array<uint8_t, 32> calculatedHmac;
3510 std::unique_ptr<VerifiedInputEvent> result;
3511 switch (event.getType()) {
3512 case AINPUT_EVENT_TYPE_KEY: {
3513 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
3514 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
3515 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
3516 calculatedHmac = mHmacKeyManager.sign(verifiedKeyEvent);
3517 break;
3518 }
3519 case AINPUT_EVENT_TYPE_MOTION: {
3520 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
3521 VerifiedMotionEvent verifiedMotionEvent =
3522 verifiedMotionEventFromMotionEvent(motionEvent);
3523 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
3524 calculatedHmac = mHmacKeyManager.sign(verifiedMotionEvent);
3525 break;
3526 }
3527 default: {
3528 ALOGE("Cannot verify events of type %" PRId32, event.getType());
3529 return nullptr;
3530 }
3531 }
3532 if (calculatedHmac == INVALID_HMAC) {
3533 return nullptr;
3534 }
3535 if (calculatedHmac != event.getHmac()) {
3536 return nullptr;
3537 }
3538 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003539}
3540
Michael Wrightd02c5b62014-02-10 15:10:22 -08003541bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003542 return injectorUid == 0 ||
3543 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003544}
3545
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003546void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003547 InjectionState* injectionState = entry->injectionState;
3548 if (injectionState) {
3549#if DEBUG_INJECTION
3550 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003551 "injectorPid=%d, injectorUid=%d",
3552 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003553#endif
3554
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003555 if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003556 // Log the outcome since the injector did not wait for the injection result.
3557 switch (injectionResult) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003558 case INPUT_EVENT_INJECTION_SUCCEEDED:
3559 ALOGV("Asynchronous input event injection succeeded.");
3560 break;
3561 case INPUT_EVENT_INJECTION_FAILED:
3562 ALOGW("Asynchronous input event injection failed.");
3563 break;
3564 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3565 ALOGW("Asynchronous input event injection permission denied.");
3566 break;
3567 case INPUT_EVENT_INJECTION_TIMED_OUT:
3568 ALOGW("Asynchronous input event injection timed out.");
3569 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003570 }
3571 }
3572
3573 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003574 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003575 }
3576}
3577
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003578void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003579 InjectionState* injectionState = entry->injectionState;
3580 if (injectionState) {
3581 injectionState->pendingForegroundDispatches += 1;
3582 }
3583}
3584
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003585void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003586 InjectionState* injectionState = entry->injectionState;
3587 if (injectionState) {
3588 injectionState->pendingForegroundDispatches -= 1;
3589
3590 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003591 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003592 }
3593 }
3594}
3595
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003596std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3597 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003598 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003599}
3600
Siarhei Vishniakou265ab012020-09-08 19:43:33 -05003601sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
3602 return getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3603}
3604
Michael Wrightd02c5b62014-02-10 15:10:22 -08003605sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003606 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08003607 if (windowHandleToken == nullptr) {
3608 return nullptr;
3609 }
3610
Arthur Hungb92218b2018-08-14 12:00:21 +08003611 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003612 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3613 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003614 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003615 return windowHandle;
3616 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003617 }
3618 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003619 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003620}
3621
Mady Mellor017bcd12020-06-23 19:12:00 +00003622bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
3623 for (auto& it : mWindowHandlesByDisplay) {
3624 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3625 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08003626 if (handle->getId() == windowHandle->getId() &&
3627 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00003628 if (windowHandle->getInfo()->displayId != it.first) {
3629 ALOGE("Found window %s in display %" PRId32
3630 ", but it should belong to display %" PRId32,
3631 windowHandle->getName().c_str(), it.first,
3632 windowHandle->getInfo()->displayId);
3633 }
3634 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08003635 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003636 }
3637 }
3638 return false;
3639}
3640
Robert Carr5c8a0262018-10-03 16:30:44 -07003641sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3642 size_t count = mInputChannelsByToken.count(token);
3643 if (count == 0) {
3644 return nullptr;
3645 }
3646 return mInputChannelsByToken.at(token);
3647}
3648
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003649void InputDispatcher::updateWindowHandlesForDisplayLocked(
3650 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3651 if (inputWindowHandles.empty()) {
3652 // Remove all handles on a display if there are no windows left.
3653 mWindowHandlesByDisplay.erase(displayId);
3654 return;
3655 }
3656
3657 // Since we compare the pointer of input window handles across window updates, we need
3658 // to make sure the handle object for the same window stays unchanged across updates.
3659 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003660 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003661 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003662 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003663 }
3664
3665 std::vector<sp<InputWindowHandle>> newHandles;
3666 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3667 if (!handle->updateInfo()) {
3668 // handle no longer valid
3669 continue;
3670 }
3671
3672 const InputWindowInfo* info = handle->getInfo();
3673 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3674 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3675 const bool noInputChannel =
3676 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3677 const bool canReceiveInput =
3678 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3679 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3680 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003681 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003682 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07003683 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003684 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003685 }
3686
3687 if (info->displayId != displayId) {
3688 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3689 handle->getName().c_str(), displayId, info->displayId);
3690 continue;
3691 }
3692
Robert Carredd13602020-04-13 17:24:34 -07003693 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
3694 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07003695 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003696 oldHandle->updateFrom(handle);
3697 newHandles.push_back(oldHandle);
3698 } else {
3699 newHandles.push_back(handle);
3700 }
3701 }
3702
3703 // Insert or replace
3704 mWindowHandlesByDisplay[displayId] = newHandles;
3705}
3706
Arthur Hung72d8dc32020-03-28 00:48:39 +00003707void InputDispatcher::setInputWindows(
3708 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
3709 { // acquire lock
3710 std::scoped_lock _l(mLock);
3711 for (auto const& i : handlesPerDisplay) {
3712 setInputWindowsLocked(i.second, i.first);
3713 }
3714 }
3715 // Wake up poll loop since it may need to make new input dispatching choices.
3716 mLooper->wake();
3717}
3718
Arthur Hungb92218b2018-08-14 12:00:21 +08003719/**
3720 * Called from InputManagerService, update window handle list by displayId that can receive input.
3721 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3722 * If set an empty list, remove all handles from the specific display.
3723 * For focused handle, check if need to change and send a cancel event to previous one.
3724 * For removed handle, check if need to send a cancel event if already in touch.
3725 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00003726void InputDispatcher::setInputWindowsLocked(
3727 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003728 if (DEBUG_FOCUS) {
3729 std::string windowList;
3730 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
3731 windowList += iwh->getName() + " ";
3732 }
3733 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
3734 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003735
Arthur Hung72d8dc32020-03-28 00:48:39 +00003736 // Copy old handles for release if they are no longer present.
3737 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003738
Arthur Hung72d8dc32020-03-28 00:48:39 +00003739 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003740
Arthur Hung72d8dc32020-03-28 00:48:39 +00003741 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
3742 bool foundHoveredWindow = false;
3743 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3744 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3745 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3746 windowHandle->getInfo()->visible) {
3747 newFocusedWindowHandle = windowHandle;
3748 }
3749 if (windowHandle == mLastHoverWindowHandle) {
3750 foundHoveredWindow = true;
3751 }
3752 }
3753
3754 if (!foundHoveredWindow) {
3755 mLastHoverWindowHandle = nullptr;
3756 }
3757
3758 sp<InputWindowHandle> oldFocusedWindowHandle =
3759 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3760
3761 if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
3762 if (oldFocusedWindowHandle != nullptr) {
3763 if (DEBUG_FOCUS) {
3764 ALOGD("Focus left window: %s in display %" PRId32,
3765 oldFocusedWindowHandle->getName().c_str(), displayId);
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003766 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00003767 sp<InputChannel> focusedInputChannel =
3768 getInputChannelLocked(oldFocusedWindowHandle->getToken());
3769 if (focusedInputChannel != nullptr) {
3770 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3771 "focus left window");
3772 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
3773 enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003774 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00003775 mFocusedWindowHandlesByDisplay.erase(displayId);
3776 }
3777 if (newFocusedWindowHandle != nullptr) {
3778 if (DEBUG_FOCUS) {
3779 ALOGD("Focus entered window: %s in display %" PRId32,
3780 newFocusedWindowHandle->getName().c_str(), displayId);
3781 }
3782 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
3783 enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003784 }
3785
Arthur Hung72d8dc32020-03-28 00:48:39 +00003786 if (mFocusedDisplayId == displayId) {
3787 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003788 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00003789 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003790
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07003791 std::unordered_map<int32_t, TouchState>::iterator stateIt =
3792 mTouchStatesByDisplay.find(displayId);
3793 if (stateIt != mTouchStatesByDisplay.end()) {
3794 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00003795 for (size_t i = 0; i < state.windows.size();) {
3796 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00003797 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003798 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00003799 ALOGD("Touched window was removed: %s in display %" PRId32,
3800 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003801 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00003802 sp<InputChannel> touchedInputChannel =
3803 getInputChannelLocked(touchedWindow.windowHandle->getToken());
3804 if (touchedInputChannel != nullptr) {
3805 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3806 "touched window was removed");
3807 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003808 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00003809 state.windows.erase(state.windows.begin() + i);
3810 } else {
3811 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003812 }
3813 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00003814 }
Arthur Hung25e2af12020-03-26 12:58:37 +00003815
Arthur Hung72d8dc32020-03-28 00:48:39 +00003816 // Release information for windows that are no longer present.
3817 // This ensures that unused input channels are released promptly.
3818 // Otherwise, they might stick around until the window handle is destroyed
3819 // which might not happen until the next GC.
3820 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00003821 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00003822 if (DEBUG_FOCUS) {
3823 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00003824 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00003825 oldWindowHandle->releaseChannel();
Arthur Hung25e2af12020-03-26 12:58:37 +00003826 }
chaviw291d88a2019-02-14 10:33:58 -08003827 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003828}
3829
3830void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003831 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003832 if (DEBUG_FOCUS) {
3833 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
3834 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
3835 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003836 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003837 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003838
Tiger Huang721e26f2018-07-24 22:26:19 +08003839 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3840 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07003841
3842 if (oldFocusedApplicationHandle == mAwaitedFocusedApplication &&
3843 inputApplicationHandle != oldFocusedApplicationHandle) {
3844 resetNoFocusedWindowTimeoutLocked();
3845 }
3846
Yi Kong9b14ac62018-07-17 13:48:38 -07003847 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003848 if (oldFocusedApplicationHandle != inputApplicationHandle) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003849 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003850 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003851 } else if (oldFocusedApplicationHandle != nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003852 oldFocusedApplicationHandle.clear();
3853 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003854 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003855 } // release lock
3856
3857 // Wake up poll loop since it may need to make new input dispatching choices.
3858 mLooper->wake();
3859}
3860
Tiger Huang721e26f2018-07-24 22:26:19 +08003861/**
3862 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3863 * the display not specified.
3864 *
3865 * We track any unreleased events for each window. If a window loses the ability to receive the
3866 * released event, we will send a cancel event to it. So when the focused display is changed, we
3867 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3868 * display. The display-specified events won't be affected.
3869 */
3870void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003871 if (DEBUG_FOCUS) {
3872 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3873 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003874 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003875 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003876
3877 if (mFocusedDisplayId != displayId) {
3878 sp<InputWindowHandle> oldFocusedWindowHandle =
3879 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3880 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003881 sp<InputChannel> inputChannel =
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003882 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003883 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003884 CancelationOptions
3885 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3886 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003887 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003888 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3889 }
3890 }
3891 mFocusedDisplayId = displayId;
3892
3893 // Sanity check
3894 sp<InputWindowHandle> newFocusedWindowHandle =
3895 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003896 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003897
Tiger Huang721e26f2018-07-24 22:26:19 +08003898 if (newFocusedWindowHandle == nullptr) {
3899 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3900 if (!mFocusedWindowHandlesByDisplay.empty()) {
3901 ALOGE("But another display has a focused window:");
3902 for (auto& it : mFocusedWindowHandlesByDisplay) {
3903 const int32_t displayId = it.first;
3904 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003905 ALOGE("Display #%" PRId32 " has focused window: '%s'\n", displayId,
3906 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003907 }
3908 }
3909 }
3910 }
3911
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003912 if (DEBUG_FOCUS) {
3913 logDispatchStateLocked();
3914 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003915 } // release lock
3916
3917 // Wake up poll loop since it may need to make new input dispatching choices.
3918 mLooper->wake();
3919}
3920
Michael Wrightd02c5b62014-02-10 15:10:22 -08003921void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003922 if (DEBUG_FOCUS) {
3923 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3924 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003925
3926 bool changed;
3927 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003928 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003929
3930 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3931 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07003932 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003933 }
3934
3935 if (mDispatchEnabled && !enabled) {
3936 resetAndDropEverythingLocked("dispatcher is being disabled");
3937 }
3938
3939 mDispatchEnabled = enabled;
3940 mDispatchFrozen = frozen;
3941 changed = true;
3942 } else {
3943 changed = false;
3944 }
3945
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003946 if (DEBUG_FOCUS) {
3947 logDispatchStateLocked();
3948 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003949 } // release lock
3950
3951 if (changed) {
3952 // Wake up poll loop since it may need to make new input dispatching choices.
3953 mLooper->wake();
3954 }
3955}
3956
3957void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003958 if (DEBUG_FOCUS) {
3959 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3960 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003961
3962 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003963 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003964
3965 if (mInputFilterEnabled == enabled) {
3966 return;
3967 }
3968
3969 mInputFilterEnabled = enabled;
3970 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3971 } // release lock
3972
3973 // Wake up poll loop since there might be work to do to drop everything.
3974 mLooper->wake();
3975}
3976
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08003977void InputDispatcher::setInTouchMode(bool inTouchMode) {
3978 std::scoped_lock lock(mLock);
3979 mInTouchMode = inTouchMode;
3980}
3981
chaviwfbe5d9c2018-12-26 12:23:37 -08003982bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3983 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003984 if (DEBUG_FOCUS) {
3985 ALOGD("Trivial transfer to same window.");
3986 }
chaviwfbe5d9c2018-12-26 12:23:37 -08003987 return true;
3988 }
3989
Michael Wrightd02c5b62014-02-10 15:10:22 -08003990 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003991 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003992
chaviwfbe5d9c2018-12-26 12:23:37 -08003993 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3994 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003995 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003996 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003997 return false;
3998 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003999 if (DEBUG_FOCUS) {
4000 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4001 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4002 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004003 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004004 if (DEBUG_FOCUS) {
4005 ALOGD("Cannot transfer focus because windows are on different displays.");
4006 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004007 return false;
4008 }
4009
4010 bool found = false;
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07004011 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4012 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004013 for (size_t i = 0; i < state.windows.size(); i++) {
4014 const TouchedWindow& touchedWindow = state.windows[i];
4015 if (touchedWindow.windowHandle == fromWindowHandle) {
4016 int32_t oldTargetFlags = touchedWindow.targetFlags;
4017 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004018
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004019 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004020
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004021 int32_t newTargetFlags = oldTargetFlags &
4022 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4023 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004024 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004025
Jeff Brownf086ddb2014-02-11 14:28:48 -08004026 found = true;
4027 goto Found;
4028 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004029 }
4030 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004031 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004032
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004033 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004034 if (DEBUG_FOCUS) {
4035 ALOGD("Focus transfer failed because from window did not have focus.");
4036 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004037 return false;
4038 }
4039
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004040 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4041 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004042 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004043 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004044 CancelationOptions
4045 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4046 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004047 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004048 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004049 }
4050
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004051 if (DEBUG_FOCUS) {
4052 logDispatchStateLocked();
4053 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004054 } // release lock
4055
4056 // Wake up poll loop since it may need to make new input dispatching choices.
4057 mLooper->wake();
4058 return true;
4059}
4060
4061void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004062 if (DEBUG_FOCUS) {
4063 ALOGD("Resetting and dropping all events (%s).", reason);
4064 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004065
4066 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4067 synthesizeCancelationEventsForAllConnectionsLocked(options);
4068
4069 resetKeyRepeatLocked();
4070 releasePendingEventLocked();
4071 drainInboundQueueLocked();
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004072 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004073
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004074 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004075 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004076 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004077 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004078}
4079
4080void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004081 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004082 dumpDispatchStateLocked(dump);
4083
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004084 std::istringstream stream(dump);
4085 std::string line;
4086
4087 while (std::getline(stream, line, '\n')) {
4088 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004089 }
4090}
4091
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004092void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004093 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4094 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4095 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004096 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004097
Tiger Huang721e26f2018-07-24 22:26:19 +08004098 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4099 dump += StringPrintf(INDENT "FocusedApplications:\n");
4100 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4101 const int32_t displayId = it.first;
4102 const sp<InputApplicationHandle>& applicationHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004103 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004104 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004105 displayId, applicationHandle->getName().c_str(),
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004106 ns2ms(applicationHandle
4107 ->getDispatchingTimeout(
4108 DEFAULT_INPUT_DISPATCHING_TIMEOUT)
4109 .count()));
Tiger Huang721e26f2018-07-24 22:26:19 +08004110 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004111 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004112 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004113 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004114
4115 if (!mFocusedWindowHandlesByDisplay.empty()) {
4116 dump += StringPrintf(INDENT "FocusedWindows:\n");
4117 for (auto& it : mFocusedWindowHandlesByDisplay) {
4118 const int32_t displayId = it.first;
4119 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004120 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
4121 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004122 }
4123 } else {
4124 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
4125 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004126
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07004127 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004128 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07004129 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4130 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004131 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004132 state.displayId, toString(state.down), toString(state.split),
4133 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004134 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004135 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004136 for (size_t i = 0; i < state.windows.size(); i++) {
4137 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004138 dump += StringPrintf(INDENT4
4139 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4140 i, touchedWindow.windowHandle->getName().c_str(),
4141 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004142 }
4143 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004144 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004145 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004146 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004147 dump += INDENT3 "Portal windows:\n";
4148 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004149 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004150 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4151 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004152 }
4153 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004154 }
4155 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004156 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004157 }
4158
Arthur Hungb92218b2018-08-14 12:00:21 +08004159 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004160 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004161 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004162 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004163 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004164 dump += INDENT2 "Windows:\n";
4165 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004166 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004167 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004168
Arthur Hungb92218b2018-08-14 12:00:21 +08004169 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004170 "portalToDisplayId=%d, paused=%s, hasFocus=%s, "
chaviwcb923212019-12-30 14:05:11 -08004171 "hasWallpaper=%s, visible=%s, canReceiveKeys=%s, "
4172 "flags=0x%08x, type=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004173 "frame=[%d,%d][%d,%d], globalScale=%f, "
chaviwcb923212019-12-30 14:05:11 -08004174 "windowScale=(%f,%f), touchableRegion=",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004175 i, windowInfo->name.c_str(), windowInfo->displayId,
4176 windowInfo->portalToDisplayId,
4177 toString(windowInfo->paused),
4178 toString(windowInfo->hasFocus),
4179 toString(windowInfo->hasWallpaper),
4180 toString(windowInfo->visible),
4181 toString(windowInfo->canReceiveKeys),
4182 windowInfo->layoutParamsFlags,
chaviwcb923212019-12-30 14:05:11 -08004183 windowInfo->layoutParamsType, windowInfo->frameLeft,
4184 windowInfo->frameTop, windowInfo->frameRight,
4185 windowInfo->frameBottom, windowInfo->globalScaleFactor,
4186 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08004187 dumpRegion(dump, windowInfo->touchableRegion);
4188 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004189 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
4190 "ms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004191 windowInfo->ownerPid, windowInfo->ownerUid,
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004192 ns2ms(windowInfo->dispatchingTimeout));
Arthur Hungb92218b2018-08-14 12:00:21 +08004193 }
4194 } else {
4195 dump += INDENT2 "Windows: <none>\n";
4196 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004197 }
4198 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004199 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004200 }
4201
Michael Wright3dd60e22019-03-27 22:06:44 +00004202 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004203 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004204 const std::vector<Monitor>& monitors = it.second;
4205 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4206 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004207 }
4208 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004209 const std::vector<Monitor>& monitors = it.second;
4210 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4211 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004212 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004213 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004214 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004215 }
4216
4217 nsecs_t currentTime = now();
4218
4219 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004220 if (!mRecentQueue.empty()) {
4221 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
4222 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004223 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004224 entry->appendDescription(dump);
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004225 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004226 }
4227 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004228 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004229 }
4230
4231 // Dump event currently being dispatched.
4232 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004233 dump += INDENT "PendingEvent:\n";
4234 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004235 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004236 dump += StringPrintf(", age=%" PRId64 "ms\n",
4237 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004238 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004239 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004240 }
4241
4242 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004243 if (!mInboundQueue.empty()) {
4244 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
4245 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004246 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004247 entry->appendDescription(dump);
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004248 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004249 }
4250 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004251 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004252 }
4253
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07004254 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004255 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07004256 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4257 const KeyReplacement& replacement = pair.first;
4258 int32_t newKeyCode = pair.second;
4259 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004260 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004261 }
4262 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004263 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004264 }
4265
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004266 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004267 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004268 for (const auto& pair : mConnectionsByFd) {
4269 const sp<Connection>& connection = pair.second;
4270 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004271 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004272 pair.first, connection->getInputChannelName().c_str(),
4273 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004274 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004275
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004276 if (!connection->outboundQueue.empty()) {
4277 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4278 connection->outboundQueue.size());
4279 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004280 dump.append(INDENT4);
4281 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004282 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64
4283 "ms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004284 entry->targetFlags, entry->resolvedAction,
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004285 ns2ms(currentTime - entry->eventEntry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004286 }
4287 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004288 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004289 }
4290
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004291 if (!connection->waitQueue.empty()) {
4292 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4293 connection->waitQueue.size());
4294 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004295 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004296 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004297 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004298 "age=%" PRId64 "ms, wait=%" PRId64 "ms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004299 entry->targetFlags, entry->resolvedAction,
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004300 ns2ms(currentTime - entry->eventEntry->eventTime),
4301 ns2ms(currentTime - entry->deliveryTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004302 }
4303 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004304 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004305 }
4306 }
4307 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004308 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004309 }
4310
4311 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004312 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4313 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004314 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004315 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004316 }
4317
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004318 dump += INDENT "Configuration:\n";
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004319 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4320 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4321 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004322}
4323
Michael Wright3dd60e22019-03-27 22:06:44 +00004324void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4325 const size_t numMonitors = monitors.size();
4326 for (size_t i = 0; i < numMonitors; i++) {
4327 const Monitor& monitor = monitors[i];
4328 const sp<InputChannel>& channel = monitor.inputChannel;
4329 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4330 dump += "\n";
4331 }
4332}
4333
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004334status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004335#if DEBUG_REGISTRATION
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -07004336 ALOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004337#endif
4338
4339 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004340 std::scoped_lock _l(mLock);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004341 sp<Connection> existingConnection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004342 if (existingConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004343 ALOGW("Attempted to register already registered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004344 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004345 return BAD_VALUE;
4346 }
4347
Garfield Tan1c7bc862020-01-28 13:24:04 -08004348 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004349
4350 int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004351 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004352 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004353
Michael Wrightd02c5b62014-02-10 15:10:22 -08004354 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4355 } // release lock
4356
4357 // Wake the looper because some connections have changed.
4358 mLooper->wake();
4359 return OK;
4360}
4361
Michael Wright3dd60e22019-03-27 22:06:44 +00004362status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004363 int32_t displayId, bool isGestureMonitor) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004364 { // acquire lock
4365 std::scoped_lock _l(mLock);
4366
4367 if (displayId < 0) {
4368 ALOGW("Attempted to register input monitor without a specified display.");
4369 return BAD_VALUE;
4370 }
4371
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004372 if (inputChannel->getConnectionToken() == nullptr) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004373 ALOGW("Attempted to register input monitor without an identifying token.");
4374 return BAD_VALUE;
4375 }
4376
Garfield Tan1c7bc862020-01-28 13:24:04 -08004377 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004378
4379 const int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004380 mConnectionsByFd[fd] = connection;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004381 mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004382
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004383 auto& monitorsByDisplay =
4384 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Michael Wright3dd60e22019-03-27 22:06:44 +00004385 monitorsByDisplay[displayId].emplace_back(inputChannel);
4386
4387 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004388 }
4389 // Wake the looper because some connections have changed.
4390 mLooper->wake();
4391 return OK;
4392}
4393
Michael Wrightd02c5b62014-02-10 15:10:22 -08004394status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
4395#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004396 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004397#endif
4398
4399 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004400 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004401
4402 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
4403 if (status) {
4404 return status;
4405 }
4406 } // release lock
4407
4408 // Wake the poll loop because removing the connection may have changed the current
4409 // synchronization state.
4410 mLooper->wake();
4411 return OK;
4412}
4413
4414status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004415 bool notify) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004416 sp<Connection> connection = getConnectionLocked(inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004417 if (connection == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004418 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004419 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004420 return BAD_VALUE;
4421 }
4422
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004423 removeConnectionLocked(connection);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004424 mInputChannelsByToken.erase(inputChannel->getConnectionToken());
Robert Carr5c8a0262018-10-03 16:30:44 -07004425
Michael Wrightd02c5b62014-02-10 15:10:22 -08004426 if (connection->monitor) {
4427 removeMonitorChannelLocked(inputChannel);
4428 }
4429
4430 mLooper->removeFd(inputChannel->getFd());
4431
4432 nsecs_t currentTime = now();
4433 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4434
4435 connection->status = Connection::STATUS_ZOMBIE;
4436 return OK;
4437}
4438
4439void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004440 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4441 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4442}
4443
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004444void InputDispatcher::removeMonitorChannelLocked(
4445 const sp<InputChannel>& inputChannel,
Michael Wright3dd60e22019-03-27 22:06:44 +00004446 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004447 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004448 std::vector<Monitor>& monitors = it->second;
4449 const size_t numMonitors = monitors.size();
4450 for (size_t i = 0; i < numMonitors; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004451 if (monitors[i].inputChannel == inputChannel) {
4452 monitors.erase(monitors.begin() + i);
4453 break;
4454 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004455 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004456 if (monitors.empty()) {
4457 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004458 } else {
4459 ++it;
4460 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004461 }
4462}
4463
Michael Wright3dd60e22019-03-27 22:06:44 +00004464status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4465 { // acquire lock
4466 std::scoped_lock _l(mLock);
4467 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4468
4469 if (!foundDisplayId) {
4470 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4471 return BAD_VALUE;
4472 }
4473 int32_t displayId = foundDisplayId.value();
4474
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07004475 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4476 mTouchStatesByDisplay.find(displayId);
4477 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004478 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4479 return BAD_VALUE;
4480 }
4481
Siarhei Vishniakoubde3d9e2020-03-24 19:05:54 -07004482 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00004483 std::optional<int32_t> foundDeviceId;
4484 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004485 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004486 foundDeviceId = state.deviceId;
4487 }
4488 }
4489 if (!foundDeviceId || !state.down) {
4490 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004491 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004492 return BAD_VALUE;
4493 }
4494 int32_t deviceId = foundDeviceId.value();
4495
4496 // Send cancel events to all the input channels we're stealing from.
4497 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004498 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004499 options.deviceId = deviceId;
4500 options.displayId = displayId;
4501 for (const TouchedWindow& window : state.windows) {
4502 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004503 if (channel != nullptr) {
4504 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4505 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004506 }
4507 // Then clear the current touch state so we stop dispatching to them as well.
4508 state.filterNonMonitors();
4509 }
4510 return OK;
4511}
4512
Michael Wright3dd60e22019-03-27 22:06:44 +00004513std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4514 const sp<IBinder>& token) {
4515 for (const auto& it : mGestureMonitorsByDisplay) {
4516 const std::vector<Monitor>& monitors = it.second;
4517 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004518 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004519 return it.first;
4520 }
4521 }
4522 }
4523 return std::nullopt;
4524}
4525
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004526sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004527 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004528 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004529 }
4530
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004531 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004532 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004533 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004534 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004535 }
4536 }
Robert Carr4e670e52018-08-15 13:26:12 -07004537
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004538 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004539}
4540
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004541void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004542 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004543 removeByValue(mConnectionsByFd, connection);
4544}
4545
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004546void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4547 const sp<Connection>& connection, uint32_t seq,
4548 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004549 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4550 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004551 commandEntry->connection = connection;
4552 commandEntry->eventTime = currentTime;
4553 commandEntry->seq = seq;
4554 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004555 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004556}
4557
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004558void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4559 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004560 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004561 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004562
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004563 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4564 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004565 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004566 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004567}
4568
chaviw0c06c6e2019-01-09 13:27:07 -08004569void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004570 const sp<InputWindowHandle>& newFocus) {
chaviw0c06c6e2019-01-09 13:27:07 -08004571 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4572 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004573 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4574 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004575 commandEntry->oldToken = oldToken;
4576 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004577 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004578}
4579
Siarhei Vishniakou4e219792020-09-22 21:43:09 -05004580void InputDispatcher::onAnrLocked(const Connection& connection) {
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004581 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
4582 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou4e219792020-09-22 21:43:09 -05004583 if (connection.waitQueue.empty()) {
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004584 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou4e219792020-09-22 21:43:09 -05004585 connection.inputChannel->getName().c_str());
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004586 return;
4587 }
4588 /**
4589 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
4590 * may not be the one that caused the timeout to occur. One possibility is that window timeout
4591 * has changed. This could cause newer entries to time out before the already dispatched
4592 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
4593 * processes the events linearly. So providing information about the oldest entry seems to be
4594 * most useful.
4595 */
Siarhei Vishniakou4e219792020-09-22 21:43:09 -05004596 DispatchEntry* oldestEntry = *connection.waitQueue.begin();
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004597 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
4598 std::string reason =
4599 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou4e219792020-09-22 21:43:09 -05004600 connection.inputChannel->getName().c_str(),
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004601 ns2ms(currentWait),
4602 oldestEntry->eventEntry->getDescription().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004603
Siarhei Vishniakou4e219792020-09-22 21:43:09 -05004604 updateLastAnrStateLocked(getWindowHandleLocked(connection.inputChannel->getConnectionToken()),
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004605 reason);
4606
4607 std::unique_ptr<CommandEntry> commandEntry =
4608 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyAnrLockedInterruptible);
4609 commandEntry->inputApplicationHandle = nullptr;
Siarhei Vishniakou4e219792020-09-22 21:43:09 -05004610 commandEntry->inputChannel = connection.inputChannel;
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004611 commandEntry->reason = std::move(reason);
4612 postCommandLocked(std::move(commandEntry));
4613}
4614
4615void InputDispatcher::onAnrLocked(const sp<InputApplicationHandle>& application) {
4616 std::string reason = android::base::StringPrintf("%s does not have a focused window",
4617 application->getName().c_str());
4618
4619 updateLastAnrStateLocked(application, reason);
4620
4621 std::unique_ptr<CommandEntry> commandEntry =
4622 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyAnrLockedInterruptible);
4623 commandEntry->inputApplicationHandle = application;
4624 commandEntry->inputChannel = nullptr;
4625 commandEntry->reason = std::move(reason);
4626 postCommandLocked(std::move(commandEntry));
4627}
4628
4629void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
4630 const std::string& reason) {
4631 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
4632 updateLastAnrStateLocked(windowLabel, reason);
4633}
4634
4635void InputDispatcher::updateLastAnrStateLocked(const sp<InputApplicationHandle>& application,
4636 const std::string& reason) {
4637 const std::string windowLabel = getApplicationWindowLabel(application, nullptr);
4638 updateLastAnrStateLocked(windowLabel, reason);
4639}
4640
4641void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
4642 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004643 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004644 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004645 struct tm tm;
4646 localtime_r(&t, &tm);
4647 char timestr[64];
4648 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07004649 mLastAnrState.clear();
4650 mLastAnrState += INDENT "ANR:\n";
4651 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004652 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
4653 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07004654 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004655}
4656
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004657void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004658 mLock.unlock();
4659
4660 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4661
4662 mLock.lock();
4663}
4664
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004665void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004666 sp<Connection> connection = commandEntry->connection;
4667
4668 if (connection->status != Connection::STATUS_ZOMBIE) {
4669 mLock.unlock();
4670
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004671 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004672
4673 mLock.lock();
4674 }
4675}
4676
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004677void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004678 sp<IBinder> oldToken = commandEntry->oldToken;
4679 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004680 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004681 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004682 mLock.lock();
4683}
4684
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07004685void InputDispatcher::doNotifyAnrLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004686 sp<IBinder> token =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004687 commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004688 mLock.unlock();
4689
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004690 const nsecs_t timeoutExtension =
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07004691 mPolicy->notifyAnr(commandEntry->inputApplicationHandle, token, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004692
4693 mLock.lock();
4694
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004695 if (timeoutExtension > 0) {
4696 extendAnrTimeoutsLocked(commandEntry->inputApplicationHandle, token, timeoutExtension);
4697 } else {
4698 // stop waking up for events in this connection, it is already not responding
4699 sp<Connection> connection = getConnectionLocked(token);
4700 if (connection == nullptr) {
4701 return;
4702 }
4703 cancelEventsForAnrLocked(connection);
4704 }
4705}
4706
4707void InputDispatcher::extendAnrTimeoutsLocked(const sp<InputApplicationHandle>& application,
4708 const sp<IBinder>& connectionToken,
4709 nsecs_t timeoutExtension) {
Siarhei Vishniakou4e219792020-09-22 21:43:09 -05004710 if (connectionToken == nullptr && application != nullptr) {
4711 // The ANR happened because there's no focused window
4712 mNoFocusedWindowTimeoutTime = now() + timeoutExtension;
4713 mAwaitedFocusedApplication = application;
4714 }
4715
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004716 sp<Connection> connection = getConnectionLocked(connectionToken);
4717 if (connection == nullptr) {
Siarhei Vishniakou4e219792020-09-22 21:43:09 -05004718 // It's possible that the connection already disappeared. No action necessary.
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004719 return;
4720 }
4721
4722 ALOGI("Raised ANR, but the policy wants to keep waiting on %s for %" PRId64 "ms longer",
4723 connection->inputChannel->getName().c_str(), ns2ms(timeoutExtension));
4724
4725 connection->responsive = true;
4726 const nsecs_t newTimeout = now() + timeoutExtension;
4727 for (DispatchEntry* entry : connection->waitQueue) {
4728 if (newTimeout >= entry->timeoutTime) {
4729 // Already removed old entries when connection was marked unresponsive
4730 entry->timeoutTime = newTimeout;
4731 mAnrTracker.insert(entry->timeoutTime, connectionToken);
4732 }
4733 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004734}
4735
4736void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4737 CommandEntry* commandEntry) {
4738 KeyEntry* entry = commandEntry->keyEntry;
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004739 KeyEvent event = createKeyEvent(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004740
4741 mLock.unlock();
4742
Michael Wright2b3c3302018-03-02 17:19:13 +00004743 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004744 sp<IBinder> token = commandEntry->inputChannel != nullptr
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004745 ? commandEntry->inputChannel->getConnectionToken()
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004746 : nullptr;
4747 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004748 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4749 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004750 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004751 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004752
4753 mLock.lock();
4754
4755 if (delay < 0) {
4756 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4757 } else if (!delay) {
4758 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4759 } else {
4760 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4761 entry->interceptKeyWakeupTime = now() + delay;
4762 }
4763 entry->release();
4764}
4765
chaviwfd6d3512019-03-25 13:23:49 -07004766void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4767 mLock.unlock();
4768 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4769 mLock.lock();
4770}
4771
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004772/**
4773 * Connection is responsive if it has no events in the waitQueue that are older than the
4774 * current time.
4775 */
4776static bool isConnectionResponsive(const Connection& connection) {
4777 const nsecs_t currentTime = now();
4778 for (const DispatchEntry* entry : connection.waitQueue) {
4779 if (entry->timeoutTime < currentTime) {
4780 return false;
4781 }
4782 }
4783 return true;
4784}
4785
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004786void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004787 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004788 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004789 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004790 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004791
4792 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07004793 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004794 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004795 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004796 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004797 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -07004798 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004799 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakouffaa2b12020-05-26 21:43:02 -07004800 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
4801 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004802 }
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07004803 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004804
4805 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004806 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004807 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4808 restartEvent =
4809 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07004810 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004811 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4812 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4813 handled);
4814 } else {
4815 restartEvent = false;
4816 }
4817
4818 // Dequeue the event and start the next cycle.
Siarhei Vishniakoude1bc4a2020-05-26 22:39:43 -07004819 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004820 // contents of the wait queue to have been drained, so we need to double-check
4821 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004822 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4823 if (dispatchEntryIt != connection->waitQueue.end()) {
4824 dispatchEntry = *dispatchEntryIt;
4825 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakoue4623042020-03-25 16:16:40 -07004826 mAnrTracker.erase(dispatchEntry->timeoutTime,
4827 connection->inputChannel->getConnectionToken());
4828 if (!connection->responsive) {
4829 connection->responsive = isConnectionResponsive(*connection);
4830 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004831 traceWaitQueueLength(connection);
4832 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004833 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004834 traceOutboundQueueLength(connection);
4835 } else {
4836 releaseDispatchEntry(dispatchEntry);
4837 }
4838 }
4839
4840 // Start the next dispatch cycle for this connection.
4841 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004842}
4843
4844bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004845 DispatchEntry* dispatchEntry,
4846 KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004847 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004848 if (!handled) {
4849 // Report the key as unhandled, since the fallback was not handled.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08004850 mReporter->reportUnhandledKey(keyEntry->id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004851 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004852 return false;
4853 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004854
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004855 // Get the fallback key state.
4856 // Clear it out after dispatching the UP.
4857 int32_t originalKeyCode = keyEntry->keyCode;
4858 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4859 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4860 connection->inputState.removeFallbackKey(originalKeyCode);
4861 }
4862
4863 if (handled || !dispatchEntry->hasForegroundTarget()) {
4864 // If the application handles the original key for which we previously
4865 // generated a fallback or if the window is not a foreground window,
4866 // then cancel the associated fallback key, if any.
4867 if (fallbackKeyCode != -1) {
4868 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004869#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004870 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004871 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4872 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4873 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004874#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004875 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004876 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004877
4878 mLock.unlock();
4879
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004880 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004881 keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004882
4883 mLock.lock();
4884
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004885 // Cancel the fallback key.
4886 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004887 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004888 "application handled the original non-fallback key "
4889 "or is no longer a foreground target, "
4890 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004891 options.keyCode = fallbackKeyCode;
4892 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004893 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004894 connection->inputState.removeFallbackKey(originalKeyCode);
4895 }
4896 } else {
4897 // If the application did not handle a non-fallback key, first check
4898 // that we are in a good state to perform unhandled key event processing
4899 // Then ask the policy what to do with it.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004900 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN && keyEntry->repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004901 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004902#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004903 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004904 "since this is not an initial down. "
4905 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4906 originalKeyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004907#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004908 return false;
4909 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004910
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004911 // Dispatch the unhandled key to the policy.
4912#if DEBUG_OUTBOUND_EVENT_DETAILS
4913 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004914 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4915 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004916#endif
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07004917 KeyEvent event = createKeyEvent(*keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004918
4919 mLock.unlock();
4920
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004921 bool fallback =
4922 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
4923 &event, keyEntry->policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004924
4925 mLock.lock();
4926
4927 if (connection->status != Connection::STATUS_NORMAL) {
4928 connection->inputState.removeFallbackKey(originalKeyCode);
4929 return false;
4930 }
4931
4932 // Latch the fallback keycode for this key on an initial down.
4933 // The fallback keycode cannot change at any other point in the lifecycle.
4934 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004935 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004936 fallbackKeyCode = event.getKeyCode();
4937 } else {
4938 fallbackKeyCode = AKEYCODE_UNKNOWN;
4939 }
4940 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4941 }
4942
4943 ALOG_ASSERT(fallbackKeyCode != -1);
4944
4945 // Cancel the fallback key if the policy decides not to send it anymore.
4946 // We will continue to dispatch the key to the policy but we will no
4947 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004948 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
4949 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004950#if DEBUG_OUTBOUND_EVENT_DETAILS
4951 if (fallback) {
4952 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004953 "as a fallback for %d, but on the DOWN it had requested "
4954 "to send %d instead. Fallback canceled.",
4955 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004956 } else {
4957 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004958 "but on the DOWN it had requested to send %d. "
4959 "Fallback canceled.",
4960 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004961 }
4962#endif
4963
4964 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4965 "canceling fallback, policy no longer desires it");
4966 options.keyCode = fallbackKeyCode;
4967 synthesizeCancelationEventsForConnectionLocked(connection, options);
4968
4969 fallback = false;
4970 fallbackKeyCode = AKEYCODE_UNKNOWN;
4971 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004972 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004973 }
4974 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004975
4976#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004977 {
4978 std::string msg;
4979 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4980 connection->inputState.getFallbackKeys();
4981 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004982 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004983 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004984 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004985 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004986 }
4987#endif
4988
4989 if (fallback) {
4990 // Restart the dispatch cycle using the fallback key.
4991 keyEntry->eventTime = event.getEventTime();
4992 keyEntry->deviceId = event.getDeviceId();
4993 keyEntry->source = event.getSource();
4994 keyEntry->displayId = event.getDisplayId();
4995 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4996 keyEntry->keyCode = fallbackKeyCode;
4997 keyEntry->scanCode = event.getScanCode();
4998 keyEntry->metaState = event.getMetaState();
4999 keyEntry->repeatCount = event.getRepeatCount();
5000 keyEntry->downTime = event.getDownTime();
5001 keyEntry->syntheticRepeat = false;
5002
5003#if DEBUG_OUTBOUND_EVENT_DETAILS
5004 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005005 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
5006 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005007#endif
5008 return true; // restart the event
5009 } else {
5010#if DEBUG_OUTBOUND_EVENT_DETAILS
5011 ALOGD("Unhandled key event: No fallback key.");
5012#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005013
5014 // Report the key as unhandled, since there is no fallback key.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08005015 mReporter->reportUnhandledKey(keyEntry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005016 }
5017 }
5018 return false;
5019}
5020
5021bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005022 DispatchEntry* dispatchEntry,
5023 MotionEntry* motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005024 return false;
5025}
5026
5027void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5028 mLock.unlock();
5029
5030 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5031
5032 mLock.lock();
5033}
5034
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005035KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
5036 KeyEvent event;
Garfield Tanc51d1ba2020-01-28 13:24:04 -08005037 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
Garfield Tanfbe732e2020-01-24 11:26:14 -08005038 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
5039 entry.repeatCount, entry.downTime, entry.eventTime);
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005040 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005041}
5042
Siarhei Vishniakou7f0a4392020-03-24 20:49:09 -07005043void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5044 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005045 // TODO Write some statistics about how long we spend waiting.
5046}
5047
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005048/**
5049 * Report the touch event latency to the statsd server.
5050 * Input events are reported for statistics if:
5051 * - This is a touchscreen event
5052 * - InputFilter is not enabled
5053 * - Event is not injected or synthesized
5054 *
5055 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5056 * from getting aggregated with the "old" data.
5057 */
5058void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5059 REQUIRES(mLock) {
5060 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5061 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5062 if (!reportForStatistics) {
5063 return;
5064 }
5065
5066 if (mTouchStatistics.shouldReport()) {
5067 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5068 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5069 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5070 mTouchStatistics.reset();
5071 }
5072 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5073 mTouchStatistics.addValue(latencyMicros);
5074}
5075
Michael Wrightd02c5b62014-02-10 15:10:22 -08005076void InputDispatcher::traceInboundQueueLengthLocked() {
5077 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005078 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005079 }
5080}
5081
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005082void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005083 if (ATRACE_ENABLED()) {
5084 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005085 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005086 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005087 }
5088}
5089
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005090void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005091 if (ATRACE_ENABLED()) {
5092 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005093 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005094 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005095 }
5096}
5097
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005098void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005099 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005100
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005101 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005102 dumpDispatchStateLocked(dump);
5103
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005104 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005105 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005106 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005107 }
5108}
5109
5110void InputDispatcher::monitor() {
5111 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005112 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005113 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005114 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005115}
5116
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005117/**
5118 * Wake up the dispatcher and wait until it processes all events and commands.
5119 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5120 * this method can be safely called from any thread, as long as you've ensured that
5121 * the work you are interested in completing has already been queued.
5122 */
5123bool InputDispatcher::waitForIdle() {
5124 /**
5125 * Timeout should represent the longest possible time that a device might spend processing
5126 * events and commands.
5127 */
5128 constexpr std::chrono::duration TIMEOUT = 100ms;
5129 std::unique_lock lock(mLock);
5130 mLooper->wake();
5131 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5132 return result == std::cv_status::no_timeout;
5133}
5134
Garfield Tane84e6f92019-08-29 17:28:41 -07005135} // namespace android::inputdispatcher