blob: 1bbdcbbc2407df7f7eea15c944d300083c835d6a [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
Garfield Tan15601662020-09-22 15:32:38 -070031// Log debug messages about channel creation
32#define DEBUG_CHANNEL_CREATION 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080033
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
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +000040// Log debug messages about touch occlusion
41// STOPSHIP(b/169067926): Set to false
42static constexpr bool DEBUG_TOUCH_OCCLUSION = true;
43
Michael Wrightd02c5b62014-02-10 15:10:22 -080044// Log debug messages about the app switch latency optimization.
45#define DEBUG_APP_SWITCH 0
46
47// Log debug messages about hover events.
48#define DEBUG_HOVER 0
49
Michael Wright2b3c3302018-03-02 17:19:13 +000050#include <android-base/chrono_utils.h>
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080051#include <android-base/properties.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080052#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050053#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070054#include <binder/Binder.h>
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100055#include <binder/IServiceManager.h>
56#include <com/android/internal/compat/IPlatformCompatNative.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080057#include <input/InputDevice.h>
Michael Wright44753b12020-07-08 13:48:11 +010058#include <input/InputWindow.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070059#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000060#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070061#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010062#include <statslog.h>
63#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070064#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080065
Michael Wright44753b12020-07-08 13:48:11 +010066#include <cerrno>
67#include <cinttypes>
68#include <climits>
69#include <cstddef>
70#include <ctime>
71#include <queue>
72#include <sstream>
73
74#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070075#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010076
Michael Wrightd02c5b62014-02-10 15:10:22 -080077#define INDENT " "
78#define INDENT2 " "
79#define INDENT3 " "
80#define INDENT4 " "
81
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080082using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000083using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080084using android::base::StringPrintf;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080085using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100086using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080087using android::os::InputEventInjectionResult;
88using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100089using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080090
Garfield Tane84e6f92019-08-29 17:28:41 -070091namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080092
93// Default input dispatching timeout if there is no focused application or paused window
94// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080095const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
96 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
97 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -080098
99// Amount of time to allow for all pending events to be processed when an app switch
100// key is on the way. This is used to preempt input dispatch and drop input events
101// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000102constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800103
104// Amount of time to allow for an event to be dispatched (measured since its eventTime)
105// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000106constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800107
Michael Wrightd02c5b62014-02-10 15:10:22 -0800108// 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 +0000109constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
110
111// Log a warning when an interception call takes longer than this to process.
112constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800113
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700114// Additional key latency in case a connection is still processing some motion events.
115// This will help with the case when a user touched a button that opens a new window,
116// and gives us the chance to dispatch the key to this new window.
117constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
118
Michael Wrightd02c5b62014-02-10 15:10:22 -0800119// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000120constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
121
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000122// Event log tags. See EventLogTags.logtags for reference
123constexpr int LOGTAG_INPUT_INTERACTION = 62000;
124constexpr int LOGTAG_INPUT_FOCUS = 62001;
125
Michael Wrightd02c5b62014-02-10 15:10:22 -0800126static inline nsecs_t now() {
127 return systemTime(SYSTEM_TIME_MONOTONIC);
128}
129
130static inline const char* toString(bool value) {
131 return value ? "true" : "false";
132}
133
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000134static inline const std::string toString(sp<IBinder> binder) {
135 if (binder == nullptr) {
136 return "<null>";
137 }
138 return StringPrintf("%p", binder.get());
139}
140
Michael Wrightd02c5b62014-02-10 15:10:22 -0800141static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700142 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
143 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800144}
145
146static bool isValidKeyAction(int32_t action) {
147 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700148 case AKEY_EVENT_ACTION_DOWN:
149 case AKEY_EVENT_ACTION_UP:
150 return true;
151 default:
152 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800153 }
154}
155
156static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700157 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800158 ALOGE("Key event has invalid action code 0x%x", action);
159 return false;
160 }
161 return true;
162}
163
Michael Wright7b159c92015-05-14 14:48:03 +0100164static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800165 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700166 case AMOTION_EVENT_ACTION_DOWN:
167 case AMOTION_EVENT_ACTION_UP:
168 case AMOTION_EVENT_ACTION_CANCEL:
169 case AMOTION_EVENT_ACTION_MOVE:
170 case AMOTION_EVENT_ACTION_OUTSIDE:
171 case AMOTION_EVENT_ACTION_HOVER_ENTER:
172 case AMOTION_EVENT_ACTION_HOVER_MOVE:
173 case AMOTION_EVENT_ACTION_HOVER_EXIT:
174 case AMOTION_EVENT_ACTION_SCROLL:
175 return true;
176 case AMOTION_EVENT_ACTION_POINTER_DOWN:
177 case AMOTION_EVENT_ACTION_POINTER_UP: {
178 int32_t index = getMotionEventActionPointerIndex(action);
179 return index >= 0 && index < pointerCount;
180 }
181 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
182 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
183 return actionButton != 0;
184 default:
185 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186 }
187}
188
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500189static int64_t millis(std::chrono::nanoseconds t) {
190 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
191}
192
Michael Wright7b159c92015-05-14 14:48:03 +0100193static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700194 const PointerProperties* pointerProperties) {
195 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800196 ALOGE("Motion event has invalid action code 0x%x", action);
197 return false;
198 }
199 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000200 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700201 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800202 return false;
203 }
204 BitSet32 pointerIdBits;
205 for (size_t i = 0; i < pointerCount; i++) {
206 int32_t id = pointerProperties[i].id;
207 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700208 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
209 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800210 return false;
211 }
212 if (pointerIdBits.hasBit(id)) {
213 ALOGE("Motion event has duplicate pointer id %d", id);
214 return false;
215 }
216 pointerIdBits.markBit(id);
217 }
218 return true;
219}
220
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000221static std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800222 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000223 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800224 }
225
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000226 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800227 bool first = true;
228 Region::const_iterator cur = region.begin();
229 Region::const_iterator const tail = region.end();
230 while (cur != tail) {
231 if (first) {
232 first = false;
233 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800234 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800235 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800236 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800237 cur++;
238 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000239 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800240}
241
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500242static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
243 constexpr size_t maxEntries = 50; // max events to print
244 constexpr size_t skipBegin = maxEntries / 2;
245 const size_t skipEnd = queue.size() - maxEntries / 2;
246 // skip from maxEntries / 2 ... size() - maxEntries/2
247 // only print from 0 .. skipBegin and then from skipEnd .. size()
248
249 std::string dump;
250 for (size_t i = 0; i < queue.size(); i++) {
251 const DispatchEntry& entry = *queue[i];
252 if (i >= skipBegin && i < skipEnd) {
253 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
254 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
255 continue;
256 }
257 dump.append(INDENT4);
258 dump += entry.eventEntry->getDescription();
259 dump += StringPrintf(", seq=%" PRIu32
260 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
261 entry.seq, entry.targetFlags, entry.resolvedAction,
262 ns2ms(currentTime - entry.eventEntry->eventTime));
263 if (entry.deliveryTime != 0) {
264 // This entry was delivered, so add information on how long we've been waiting
265 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
266 }
267 dump.append("\n");
268 }
269 return dump;
270}
271
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700272/**
273 * Find the entry in std::unordered_map by key, and return it.
274 * If the entry is not found, return a default constructed entry.
275 *
276 * Useful when the entries are vectors, since an empty vector will be returned
277 * if the entry is not found.
278 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
279 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700280template <typename K, typename V>
281static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700282 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700283 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800284}
285
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700286/**
287 * Find the entry in std::unordered_map by value, and remove it.
288 * If more than one entry has the same value, then all matching
289 * key-value pairs will be removed.
290 *
291 * Return true if at least one value has been removed.
292 */
293template <typename K, typename V>
294static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
295 bool removed = false;
296 for (auto it = map.begin(); it != map.end();) {
297 if (it->second == value) {
298 it = map.erase(it);
299 removed = true;
300 } else {
301 it++;
302 }
303 }
304 return removed;
305}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800306
chaviwaf87b3e2019-10-01 16:59:28 -0700307static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
308 if (first == second) {
309 return true;
310 }
311
312 if (first == nullptr || second == nullptr) {
313 return false;
314 }
315
316 return first->getToken() == second->getToken();
317}
318
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000319static bool haveSameApplicationToken(const InputWindowInfo* first, const InputWindowInfo* second) {
320 if (first == nullptr || second == nullptr) {
321 return false;
322 }
323 return first->applicationInfo.token != nullptr &&
324 first->applicationInfo.token == second->applicationInfo.token;
325}
326
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800327static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
328 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
329}
330
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000331static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700332 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000333 int32_t inputTargetFlags) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900334 if (eventEntry->type == EventEntry::Type::MOTION) {
335 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
Prabir Pradhanbd527712021-03-09 19:17:09 -0800336 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) == 0) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900337 const ui::Transform identityTransform;
Prabir Pradhanbd527712021-03-09 19:17:09 -0800338 // Use identity transform for events that are not pointer events because their axes
339 // values do not represent on-screen coordinates, so they should not have any window
340 // transformations applied to them.
yunho.shinf4a80b82020-11-16 21:13:57 +0900341 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700342 1.0f /*globalScaleFactor*/,
343 inputTarget.displaySize);
yunho.shinf4a80b82020-11-16 21:13:57 +0900344 }
345 }
346
chaviw1ff3d1e2020-07-01 15:53:47 -0700347 if (inputTarget.useDefaultPointerTransform()) {
348 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700349 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700350 inputTarget.globalScaleFactor,
351 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000352 }
353
354 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
355 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
356
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700357 std::vector<PointerCoords> pointerCoords;
358 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000359
360 // Use the first pointer information to normalize all other pointers. This could be any pointer
361 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700362 // uses the transform for the normalized pointer.
363 const ui::Transform& firstPointerTransform =
364 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
365 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000366
367 // Iterate through all pointers in the event to normalize against the first.
368 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
369 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
370 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700371 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000372
373 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700374 // First, apply the current pointer's transform to update the coordinates into
375 // window space.
376 pointerCoords[pointerIndex].transform(currTransform);
377 // Next, apply the inverse transform of the normalized coordinates so the
378 // current coordinates are transformed into the normalized coordinate space.
379 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000380 }
381
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700382 std::unique_ptr<MotionEntry> combinedMotionEntry =
383 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
384 motionEntry.deviceId, motionEntry.source,
385 motionEntry.displayId, motionEntry.policyFlags,
386 motionEntry.action, motionEntry.actionButton,
387 motionEntry.flags, motionEntry.metaState,
388 motionEntry.buttonState, motionEntry.classification,
389 motionEntry.edgeFlags, motionEntry.xPrecision,
390 motionEntry.yPrecision, motionEntry.xCursorPosition,
391 motionEntry.yCursorPosition, motionEntry.downTime,
392 motionEntry.pointerCount, motionEntry.pointerProperties,
393 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000394
395 if (motionEntry.injectionState) {
396 combinedMotionEntry->injectionState = motionEntry.injectionState;
397 combinedMotionEntry->injectionState->refCount += 1;
398 }
399
400 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700401 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Evan Rosky84f07f02021-04-16 10:42:42 -0700402 firstPointerTransform, inputTarget.globalScaleFactor,
403 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000404 return dispatchEntry;
405}
406
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700407static void addGestureMonitors(const std::vector<Monitor>& monitors,
408 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
409 float yOffset = 0) {
410 if (monitors.empty()) {
411 return;
412 }
413 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
414 for (const Monitor& monitor : monitors) {
415 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
416 }
417}
418
Garfield Tan15601662020-09-22 15:32:38 -0700419static status_t openInputChannelPair(const std::string& name,
420 std::shared_ptr<InputChannel>& serverChannel,
421 std::unique_ptr<InputChannel>& clientChannel) {
422 std::unique_ptr<InputChannel> uniqueServerChannel;
423 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
424
425 serverChannel = std::move(uniqueServerChannel);
426 return result;
427}
428
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500429template <typename T>
430static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
431 if (lhs == nullptr && rhs == nullptr) {
432 return true;
433 }
434 if (lhs == nullptr || rhs == nullptr) {
435 return false;
436 }
437 return *lhs == *rhs;
438}
439
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000440static sp<IPlatformCompatNative> getCompatService() {
441 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
442 if (service == nullptr) {
443 ALOGE("Failed to link to compat service");
444 return nullptr;
445 }
446 return interface_cast<IPlatformCompatNative>(service);
447}
448
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000449static KeyEvent createKeyEvent(const KeyEntry& entry) {
450 KeyEvent event;
451 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
452 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
453 entry.repeatCount, entry.downTime, entry.eventTime);
454 return event;
455}
456
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000457static std::optional<int32_t> findMonitorPidByToken(
458 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
459 const sp<IBinder>& token) {
460 for (const auto& it : monitorsByDisplay) {
461 const std::vector<Monitor>& monitors = it.second;
462 for (const Monitor& monitor : monitors) {
463 if (monitor.inputChannel->getConnectionToken() == token) {
464 return monitor.pid;
465 }
466 }
467 }
468 return std::nullopt;
469}
470
Michael Wrightd02c5b62014-02-10 15:10:22 -0800471// --- InputDispatcher ---
472
Garfield Tan00f511d2019-06-12 16:55:40 -0700473InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
474 : mPolicy(policy),
475 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700476 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800477 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700478 mAppSwitchSawKeyDown(false),
479 mAppSwitchDueTime(LONG_LONG_MAX),
480 mNextUnblockedEvent(nullptr),
481 mDispatchEnabled(false),
482 mDispatchFrozen(false),
483 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800484 // mInTouchMode will be initialized by the WindowManager to the default device config.
485 // To avoid leaking stack in case that call never comes, and for tests,
486 // initialize it here anyways.
487 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100488 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000489 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800490 mFocusedWindowRequestedPointerCapture(false),
491 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000492 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800493 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800494 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800495
Yi Kong9b14ac62018-07-17 13:48:38 -0700496 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800497
498 policy->getDispatcherConfiguration(&mConfig);
499}
500
501InputDispatcher::~InputDispatcher() {
502 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800503 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800504
505 resetKeyRepeatLocked();
506 releasePendingEventLocked();
507 drainInboundQueueLocked();
508 }
509
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700510 while (!mConnectionsByFd.empty()) {
511 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700512 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800513 }
514}
515
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700516status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700517 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700518 return ALREADY_EXISTS;
519 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700520 mThread = std::make_unique<InputThread>(
521 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
522 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700523}
524
525status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700526 if (mThread && mThread->isCallingThread()) {
527 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700528 return INVALID_OPERATION;
529 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700530 mThread.reset();
531 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700532}
533
Michael Wrightd02c5b62014-02-10 15:10:22 -0800534void InputDispatcher::dispatchOnce() {
535 nsecs_t nextWakeupTime = LONG_LONG_MAX;
536 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800537 std::scoped_lock _l(mLock);
538 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800539
540 // Run a dispatch loop if there are no pending commands.
541 // The dispatch loop might enqueue commands to run afterwards.
542 if (!haveCommandsLocked()) {
543 dispatchOnceInnerLocked(&nextWakeupTime);
544 }
545
546 // Run all pending commands if there are any.
547 // If any commands were run then force the next poll to wake up immediately.
548 if (runCommandsLockedInterruptible()) {
549 nextWakeupTime = LONG_LONG_MIN;
550 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800551
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700552 // If we are still waiting for ack on some events,
553 // we might have to wake up earlier to check if an app is anr'ing.
554 const nsecs_t nextAnrCheck = processAnrsLocked();
555 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
556
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800557 // We are about to enter an infinitely long sleep, because we have no commands or
558 // pending or queued events
559 if (nextWakeupTime == LONG_LONG_MAX) {
560 mDispatcherEnteredIdle.notify_all();
561 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800562 } // release lock
563
564 // Wait for callback or timeout or wake. (make sure we round up, not down)
565 nsecs_t currentTime = now();
566 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
567 mLooper->pollOnce(timeoutMillis);
568}
569
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700570/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500571 * Raise ANR if there is no focused window.
572 * Before the ANR is raised, do a final state check:
573 * 1. The currently focused application must be the same one we are waiting for.
574 * 2. Ensure we still don't have a focused window.
575 */
576void InputDispatcher::processNoFocusedWindowAnrLocked() {
577 // Check if the application that we are waiting for is still focused.
578 std::shared_ptr<InputApplicationHandle> focusedApplication =
579 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
580 if (focusedApplication == nullptr ||
581 focusedApplication->getApplicationToken() !=
582 mAwaitedFocusedApplication->getApplicationToken()) {
583 // Unexpected because we should have reset the ANR timer when focused application changed
584 ALOGE("Waited for a focused window, but focused application has already changed to %s",
585 focusedApplication->getName().c_str());
586 return; // The focused application has changed.
587 }
588
589 const sp<InputWindowHandle>& focusedWindowHandle =
590 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
591 if (focusedWindowHandle != nullptr) {
592 return; // We now have a focused window. No need for ANR.
593 }
594 onAnrLocked(mAwaitedFocusedApplication);
595}
596
597/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700598 * Check if any of the connections' wait queues have events that are too old.
599 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
600 * Return the time at which we should wake up next.
601 */
602nsecs_t InputDispatcher::processAnrsLocked() {
603 const nsecs_t currentTime = now();
604 nsecs_t nextAnrCheck = LONG_LONG_MAX;
605 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
606 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
607 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500608 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700609 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500610 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700611 return LONG_LONG_MIN;
612 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500613 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700614 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
615 }
616 }
617
618 // Check if any connection ANRs are due
619 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
620 if (currentTime < nextAnrCheck) { // most likely scenario
621 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
622 }
623
624 // If we reached here, we have an unresponsive connection.
625 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
626 if (connection == nullptr) {
627 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
628 return nextAnrCheck;
629 }
630 connection->responsive = false;
631 // Stop waking up for this unresponsive connection
632 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000633 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700634 return LONG_LONG_MIN;
635}
636
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500637std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700638 sp<InputWindowHandle> window = getWindowHandleLocked(token);
639 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500640 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700641 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500642 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700643}
644
Michael Wrightd02c5b62014-02-10 15:10:22 -0800645void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
646 nsecs_t currentTime = now();
647
Jeff Browndc5992e2014-04-11 01:27:26 -0700648 // Reset the key repeat timer whenever normal dispatch is suspended while the
649 // device is in a non-interactive state. This is to ensure that we abort a key
650 // repeat if the device is just coming out of sleep.
651 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800652 resetKeyRepeatLocked();
653 }
654
655 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
656 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100657 if (DEBUG_FOCUS) {
658 ALOGD("Dispatch frozen. Waiting some more.");
659 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800660 return;
661 }
662
663 // Optimize latency of app switches.
664 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
665 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
666 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
667 if (mAppSwitchDueTime < *nextWakeupTime) {
668 *nextWakeupTime = mAppSwitchDueTime;
669 }
670
671 // Ready to start a new event.
672 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700673 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700674 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800675 if (isAppSwitchDue) {
676 // The inbound queue is empty so the app switch key we were waiting
677 // for will never arrive. Stop waiting for it.
678 resetPendingAppSwitchLocked(false);
679 isAppSwitchDue = false;
680 }
681
682 // Synthesize a key repeat if appropriate.
683 if (mKeyRepeatState.lastKeyEntry) {
684 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
685 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
686 } else {
687 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
688 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
689 }
690 }
691 }
692
693 // Nothing to do if there is no pending event.
694 if (!mPendingEvent) {
695 return;
696 }
697 } else {
698 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700699 mPendingEvent = mInboundQueue.front();
700 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800701 traceInboundQueueLengthLocked();
702 }
703
704 // Poke user activity for this event.
705 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700706 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800707 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800708 }
709
710 // Now we have an event to dispatch.
711 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700712 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800713 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700714 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800715 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700716 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800717 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700718 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800719 }
720
721 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700722 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800723 }
724
725 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700726 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700727 const ConfigurationChangedEntry& typedEntry =
728 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700729 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700730 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700731 break;
732 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800733
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700734 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700735 const DeviceResetEntry& typedEntry =
736 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700737 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700738 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700739 break;
740 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800741
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100742 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700743 std::shared_ptr<FocusEntry> typedEntry =
744 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100745 dispatchFocusLocked(currentTime, typedEntry);
746 done = true;
747 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
748 break;
749 }
750
Prabir Pradhan99987712020-11-10 18:43:05 -0800751 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
752 const auto typedEntry =
753 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
754 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
755 done = true;
756 break;
757 }
758
arthurhungb89ccb02020-12-30 16:19:01 +0800759 case EventEntry::Type::DRAG: {
760 std::shared_ptr<DragEntry> typedEntry =
761 std::static_pointer_cast<DragEntry>(mPendingEvent);
762 dispatchDragLocked(currentTime, typedEntry);
763 done = true;
764 break;
765 }
766
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700767 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700768 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700769 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700770 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700771 resetPendingAppSwitchLocked(true);
772 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700773 } else if (dropReason == DropReason::NOT_DROPPED) {
774 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700775 }
776 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700777 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700778 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700779 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700780 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
781 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700782 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700783 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700784 break;
785 }
786
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700787 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700788 std::shared_ptr<MotionEntry> motionEntry =
789 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700790 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
791 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800792 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700793 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700794 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700795 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700796 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
797 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700798 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700799 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700800 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800801 }
Chris Yef59a2f42020-10-16 12:55:26 -0700802
803 case EventEntry::Type::SENSOR: {
804 std::shared_ptr<SensorEntry> sensorEntry =
805 std::static_pointer_cast<SensorEntry>(mPendingEvent);
806 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
807 dropReason = DropReason::APP_SWITCH;
808 }
809 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
810 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
811 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
812 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
813 dropReason = DropReason::STALE;
814 }
815 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
816 done = true;
817 break;
818 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800819 }
820
821 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700822 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700823 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800824 }
Michael Wright3a981722015-06-10 15:26:13 +0100825 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800826
827 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700828 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800829 }
830}
831
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700832/**
833 * Return true if the events preceding this incoming motion event should be dropped
834 * Return false otherwise (the default behaviour)
835 */
836bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700837 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700838 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700839
840 // Optimize case where the current application is unresponsive and the user
841 // decides to touch a window in a different application.
842 // If the application takes too long to catch up then we drop all events preceding
843 // the touch into the other window.
844 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700845 int32_t displayId = motionEntry.displayId;
846 int32_t x = static_cast<int32_t>(
847 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
848 int32_t y = static_cast<int32_t>(
849 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
850 sp<InputWindowHandle> touchedWindowHandle =
851 findTouchedWindowAtLocked(displayId, x, y, nullptr);
852 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700853 touchedWindowHandle->getApplicationToken() !=
854 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700855 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700856 ALOGI("Pruning input queue because user touched a different application while waiting "
857 "for %s",
858 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700859 return true;
860 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700861
862 // Alternatively, maybe there's a gesture monitor that could handle this event
863 std::vector<TouchedMonitor> gestureMonitors =
864 findTouchedGestureMonitorsLocked(displayId, {});
865 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
866 sp<Connection> connection =
867 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000868 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700869 // This monitor could take more input. Drop all events preceding this
870 // event, so that gesture monitor could get a chance to receive the stream
871 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
872 "responsive gesture monitor that may handle the event",
873 mAwaitedFocusedApplication->getName().c_str());
874 return true;
875 }
876 }
877 }
878
879 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
880 // yet been processed by some connections, the dispatcher will wait for these motion
881 // events to be processed before dispatching the key event. This is because these motion events
882 // may cause a new window to be launched, which the user might expect to receive focus.
883 // To prevent waiting forever for such events, just send the key to the currently focused window
884 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
885 ALOGD("Received a new pointer down event, stop waiting for events to process and "
886 "just send the pending key event to the focused window.");
887 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700888 }
889 return false;
890}
891
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700892bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700893 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700894 mInboundQueue.push_back(std::move(newEntry));
895 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800896 traceInboundQueueLengthLocked();
897
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700898 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700899 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700900 // Optimize app switch latency.
901 // If the application takes too long to catch up then we drop all events preceding
902 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700903 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700904 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700905 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700906 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700907 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700908 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800909#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700910 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800911#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700912 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700913 mAppSwitchSawKeyDown = false;
914 needWake = true;
915 }
916 }
917 }
918 break;
919 }
920
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700921 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700922 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
923 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700924 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800925 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700926 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800927 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100928 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700929 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
930 break;
931 }
932 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -0800933 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -0700934 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +0800935 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
936 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700937 // nothing to do
938 break;
939 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800940 }
941
942 return needWake;
943}
944
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700945void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -0700946 // Do not store sensor event in recent queue to avoid flooding the queue.
947 if (entry->type != EventEntry::Type::SENSOR) {
948 mRecentQueue.push_back(entry);
949 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700950 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700951 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800952 }
953}
954
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700955sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700956 int32_t y, TouchState* touchState,
957 bool addOutsideTargets,
arthurhungb89ccb02020-12-30 16:19:01 +0800958 bool addPortalWindows,
959 bool ignoreDragWindow) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700960 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
961 LOG_ALWAYS_FATAL(
962 "Must provide a valid touch state if adding portal windows or outside targets");
963 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800964 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700965 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800966 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +0800967 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +0800968 continue;
969 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800970 const InputWindowInfo* windowInfo = windowHandle->getInfo();
971 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100972 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800973
974 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100975 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
976 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
977 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800978 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800979 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700980 if (portalToDisplayId != ADISPLAY_ID_NONE &&
981 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800982 if (addPortalWindows) {
983 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700984 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800985 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700986 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700987 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800988 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800989 // Found window.
990 return windowHandle;
991 }
992 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800993
Michael Wright44753b12020-07-08 13:48:11 +0100994 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700995 touchState->addOrUpdateWindow(windowHandle,
996 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
997 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800998 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800999 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001000 }
1001 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001002 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001003}
1004
Garfield Tane84e6f92019-08-29 17:28:41 -07001005std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001006 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00001007 std::vector<TouchedMonitor> touchedMonitors;
1008
1009 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
1010 addGestureMonitors(monitors, touchedMonitors);
1011 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
1012 const InputWindowInfo* windowInfo = portalWindow->getInfo();
1013 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001014 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
1015 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +00001016 }
1017 return touchedMonitors;
1018}
1019
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001020void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001021 const char* reason;
1022 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001023 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -08001024#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001025 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001026#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001027 reason = "inbound event was dropped because the policy consumed it";
1028 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001029 case DropReason::DISABLED:
1030 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001031 ALOGI("Dropped event because input dispatch is disabled.");
1032 }
1033 reason = "inbound event was dropped because input dispatch is disabled";
1034 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001035 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001036 ALOGI("Dropped event because of pending overdue app switch.");
1037 reason = "inbound event was dropped because of pending overdue app switch";
1038 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001039 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001040 ALOGI("Dropped event because the current application is not responding and the user "
1041 "has started interacting with a different application.");
1042 reason = "inbound event was dropped because the current application is not responding "
1043 "and the user has started interacting with a different application";
1044 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001045 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001046 ALOGI("Dropped event because it is stale.");
1047 reason = "inbound event was dropped because it is stale";
1048 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001049 case DropReason::NO_POINTER_CAPTURE:
1050 ALOGI("Dropped event because there is no window with Pointer Capture.");
1051 reason = "inbound event was dropped because there is no window with Pointer Capture";
1052 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001053 case DropReason::NOT_DROPPED: {
1054 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001055 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001056 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001057 }
1058
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001059 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001060 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001061 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1062 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001063 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001064 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001065 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001066 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1067 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001068 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1069 synthesizeCancelationEventsForAllConnectionsLocked(options);
1070 } else {
1071 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1072 synthesizeCancelationEventsForAllConnectionsLocked(options);
1073 }
1074 break;
1075 }
Chris Yef59a2f42020-10-16 12:55:26 -07001076 case EventEntry::Type::SENSOR: {
1077 break;
1078 }
arthurhungb89ccb02020-12-30 16:19:01 +08001079 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1080 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001081 break;
1082 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001083 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001084 case EventEntry::Type::CONFIGURATION_CHANGED:
1085 case EventEntry::Type::DEVICE_RESET: {
Chris Yef59a2f42020-10-16 12:55:26 -07001086 LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001087 break;
1088 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001089 }
1090}
1091
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001092static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001093 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1094 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001095}
1096
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001097bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1098 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1099 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1100 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001101}
1102
1103bool InputDispatcher::isAppSwitchPendingLocked() {
1104 return mAppSwitchDueTime != LONG_LONG_MAX;
1105}
1106
1107void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1108 mAppSwitchDueTime = LONG_LONG_MAX;
1109
1110#if DEBUG_APP_SWITCH
1111 if (handled) {
1112 ALOGD("App switch has arrived.");
1113 } else {
1114 ALOGD("App switch was abandoned.");
1115 }
1116#endif
1117}
1118
Michael Wrightd02c5b62014-02-10 15:10:22 -08001119bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001120 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001121}
1122
1123bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001124 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001125 return false;
1126 }
1127
1128 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001129 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001130 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001131 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001132 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001133
1134 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001135 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001136 return true;
1137}
1138
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001139void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1140 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001141}
1142
1143void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001144 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001145 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001146 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001147 releaseInboundEventLocked(entry);
1148 }
1149 traceInboundQueueLengthLocked();
1150}
1151
1152void InputDispatcher::releasePendingEventLocked() {
1153 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001154 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001155 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001156 }
1157}
1158
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001159void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001160 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001161 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001162#if DEBUG_DISPATCH_CYCLE
1163 ALOGD("Injected inbound event was dropped.");
1164#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001165 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001166 }
1167 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001168 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001169 }
1170 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001171}
1172
1173void InputDispatcher::resetKeyRepeatLocked() {
1174 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001175 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001176 }
1177}
1178
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001179std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1180 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001181
Michael Wright2e732952014-09-24 13:26:59 -07001182 uint32_t policyFlags = entry->policyFlags &
1183 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001184
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001185 std::shared_ptr<KeyEntry> newEntry =
1186 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1187 entry->source, entry->displayId, policyFlags, entry->action,
1188 entry->flags, entry->keyCode, entry->scanCode,
1189 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001190
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001191 newEntry->syntheticRepeat = true;
1192 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001193 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001194 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001195}
1196
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001197bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001198 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001199#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001200 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001201#endif
1202
1203 // Reset key repeating in case a keyboard device was added or removed or something.
1204 resetKeyRepeatLocked();
1205
1206 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001207 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1208 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001209 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001210 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001211 return true;
1212}
1213
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001214bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1215 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001216#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001217 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1218 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001219#endif
1220
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001221 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001222 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001223 synthesizeCancelationEventsForAllConnectionsLocked(options);
1224 return true;
1225}
1226
Vishnu Nairad321cd2020-08-20 16:40:21 -07001227void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001228 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001229 if (mPendingEvent != nullptr) {
1230 // Move the pending event to the front of the queue. This will give the chance
1231 // for the pending event to get dispatched to the newly focused window
1232 mInboundQueue.push_front(mPendingEvent);
1233 mPendingEvent = nullptr;
1234 }
1235
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001236 std::unique_ptr<FocusEntry> focusEntry =
1237 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1238 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001239
1240 // This event should go to the front of the queue, but behind all other focus events
1241 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001242 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001243 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001244 [](const std::shared_ptr<EventEntry>& event) {
1245 return event->type == EventEntry::Type::FOCUS;
1246 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001247
1248 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001249 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001250}
1251
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001252void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001253 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001254 if (channel == nullptr) {
1255 return; // Window has gone away
1256 }
1257 InputTarget target;
1258 target.inputChannel = channel;
1259 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1260 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001261 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1262 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001263 std::string reason = std::string("reason=").append(entry->reason);
1264 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001265 dispatchEventLocked(currentTime, entry, {target});
1266}
1267
Prabir Pradhan99987712020-11-10 18:43:05 -08001268void InputDispatcher::dispatchPointerCaptureChangedLocked(
1269 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1270 DropReason& dropReason) {
1271 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan167e6d92021-02-04 16:18:17 -08001272 if (entry->pointerCaptureEnabled && haveWindowWithPointerCapture) {
1273 LOG_ALWAYS_FATAL("Pointer Capture has already been enabled for the window.");
1274 }
1275 if (!entry->pointerCaptureEnabled && !haveWindowWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001276 // Pointer capture was already forcefully disabled because of focus change.
1277 dropReason = DropReason::NOT_DROPPED;
1278 return;
1279 }
1280
1281 // Set drop reason for early returns
1282 dropReason = DropReason::NO_POINTER_CAPTURE;
1283
1284 sp<IBinder> token;
1285 if (entry->pointerCaptureEnabled) {
1286 // Enable Pointer Capture
1287 if (!mFocusedWindowRequestedPointerCapture) {
1288 // This can happen if a window requests capture and immediately releases capture.
1289 ALOGW("No window requested Pointer Capture.");
1290 return;
1291 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08001292 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001293 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1294 mWindowTokenWithPointerCapture = token;
1295 } else {
1296 // Disable Pointer Capture
1297 token = mWindowTokenWithPointerCapture;
1298 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001299 if (mFocusedWindowRequestedPointerCapture) {
1300 mFocusedWindowRequestedPointerCapture = false;
1301 setPointerCaptureLocked(false);
1302 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001303 }
1304
1305 auto channel = getInputChannelLocked(token);
1306 if (channel == nullptr) {
1307 // Window has gone away, clean up Pointer Capture state.
1308 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001309 if (mFocusedWindowRequestedPointerCapture) {
1310 mFocusedWindowRequestedPointerCapture = false;
1311 setPointerCaptureLocked(false);
1312 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001313 return;
1314 }
1315 InputTarget target;
1316 target.inputChannel = channel;
1317 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1318 entry->dispatchInProgress = true;
1319 dispatchEventLocked(currentTime, entry, {target});
1320
1321 dropReason = DropReason::NOT_DROPPED;
1322}
1323
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001324bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001325 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001326 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001327 if (!entry->dispatchInProgress) {
1328 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1329 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1330 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1331 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001332 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001333 // We have seen two identical key downs in a row which indicates that the device
1334 // driver is automatically generating key repeats itself. We take note of the
1335 // repeat here, but we disable our own next key repeat timer since it is clear that
1336 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001337 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1338 // Make sure we don't get key down from a different device. If a different
1339 // device Id has same key pressed down, the new device Id will replace the
1340 // current one to hold the key repeat with repeat count reset.
1341 // In the future when got a KEY_UP on the device id, drop it and do not
1342 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001343 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1344 resetKeyRepeatLocked();
1345 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1346 } else {
1347 // Not a repeat. Save key down state in case we do see a repeat later.
1348 resetKeyRepeatLocked();
1349 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1350 }
1351 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001352 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1353 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001354 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001355#if DEBUG_INBOUND_EVENT_DETAILS
1356 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1357#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001358 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001359 resetKeyRepeatLocked();
1360 }
1361
1362 if (entry->repeatCount == 1) {
1363 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1364 } else {
1365 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1366 }
1367
1368 entry->dispatchInProgress = true;
1369
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001370 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001371 }
1372
1373 // Handle case where the policy asked us to try again later last time.
1374 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1375 if (currentTime < entry->interceptKeyWakeupTime) {
1376 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1377 *nextWakeupTime = entry->interceptKeyWakeupTime;
1378 }
1379 return false; // wait until next wakeup
1380 }
1381 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1382 entry->interceptKeyWakeupTime = 0;
1383 }
1384
1385 // Give the policy a chance to intercept the key.
1386 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1387 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001388 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001389 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001390 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001391 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001392 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001393 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001394 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001395 return false; // wait for the command to run
1396 } else {
1397 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1398 }
1399 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001400 if (*dropReason == DropReason::NOT_DROPPED) {
1401 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001402 }
1403 }
1404
1405 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001406 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001407 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001408 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1409 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001410 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001411 return true;
1412 }
1413
1414 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001415 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001416 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001417 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001418 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001419 return false;
1420 }
1421
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001422 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001423 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001424 return true;
1425 }
1426
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001427 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001428 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001429
1430 // Dispatch the key.
1431 dispatchEventLocked(currentTime, entry, inputTargets);
1432 return true;
1433}
1434
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001435void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001436#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001437 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001438 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1439 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001440 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1441 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1442 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001443#endif
1444}
1445
Chris Yef59a2f42020-10-16 12:55:26 -07001446void InputDispatcher::doNotifySensorLockedInterruptible(CommandEntry* commandEntry) {
1447 mLock.unlock();
1448
1449 const std::shared_ptr<SensorEntry>& entry = commandEntry->sensorEntry;
1450 if (entry->accuracyChanged) {
1451 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1452 }
1453 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1454 entry->hwTimestamp, entry->values);
1455 mLock.lock();
1456}
1457
1458void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, std::shared_ptr<SensorEntry> entry,
1459 DropReason* dropReason, nsecs_t* nextWakeupTime) {
1460#if DEBUG_OUTBOUND_EVENT_DETAILS
1461 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1462 "source=0x%x, sensorType=%s",
1463 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Prabir Pradhanbe05b5b2021-02-24 16:39:43 -08001464 NamedEnum::string(entry->sensorType).c_str());
Chris Yef59a2f42020-10-16 12:55:26 -07001465#endif
1466 std::unique_ptr<CommandEntry> commandEntry =
1467 std::make_unique<CommandEntry>(&InputDispatcher::doNotifySensorLockedInterruptible);
1468 commandEntry->sensorEntry = entry;
1469 postCommandLocked(std::move(commandEntry));
1470}
1471
1472bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
1473#if DEBUG_OUTBOUND_EVENT_DETAILS
1474 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
1475 NamedEnum::string(sensorType).c_str());
1476#endif
1477 { // acquire lock
1478 std::scoped_lock _l(mLock);
1479
1480 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1481 std::shared_ptr<EventEntry> entry = *it;
1482 if (entry->type == EventEntry::Type::SENSOR) {
1483 it = mInboundQueue.erase(it);
1484 releaseInboundEventLocked(entry);
1485 }
1486 }
1487 }
1488 return true;
1489}
1490
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001491bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001492 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001493 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001494 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001495 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001496 entry->dispatchInProgress = true;
1497
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001498 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001499 }
1500
1501 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001502 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001503 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001504 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1505 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001506 return true;
1507 }
1508
1509 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1510
1511 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001512 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001513
1514 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001515 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001516 if (isPointerEvent) {
1517 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001518 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001519 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001520 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001521 } else {
1522 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001523 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001524 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001525 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001526 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001527 return false;
1528 }
1529
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001530 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001531 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001532 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1533 return true;
1534 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001535 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001536 CancelationOptions::Mode mode(isPointerEvent
1537 ? CancelationOptions::CANCEL_POINTER_EVENTS
1538 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1539 CancelationOptions options(mode, "input event injection failed");
1540 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001541 return true;
1542 }
1543
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001544 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001545 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001546
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001547 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001548 std::unordered_map<int32_t, TouchState>::iterator it =
1549 mTouchStatesByDisplay.find(entry->displayId);
1550 if (it != mTouchStatesByDisplay.end()) {
1551 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001552 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001553 // The event has gone through these portal windows, so we add monitoring targets of
1554 // the corresponding displays as well.
1555 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001556 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001557 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001558 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001559 }
1560 }
1561 }
1562 }
1563
Michael Wrightd02c5b62014-02-10 15:10:22 -08001564 // Dispatch the motion.
1565 if (conflictingPointerActions) {
1566 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001567 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001568 synthesizeCancelationEventsForAllConnectionsLocked(options);
1569 }
1570 dispatchEventLocked(currentTime, entry, inputTargets);
1571 return true;
1572}
1573
arthurhungb89ccb02020-12-30 16:19:01 +08001574void InputDispatcher::enqueueDragEventLocked(const sp<InputWindowHandle>& windowHandle,
1575 bool isExiting, const MotionEntry& motionEntry) {
1576 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1577 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1578 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1579 PointerCoords pointerCoords;
1580 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1581 pointerCoords.transform(windowHandle->getInfo()->transform);
1582
1583 std::unique_ptr<DragEntry> dragEntry =
1584 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1585 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1586 pointerCoords.getY());
1587
1588 enqueueInboundEventLocked(std::move(dragEntry));
1589}
1590
1591void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1592 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1593 if (channel == nullptr) {
1594 return; // Window has gone away
1595 }
1596 InputTarget target;
1597 target.inputChannel = channel;
1598 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1599 entry->dispatchInProgress = true;
1600 dispatchEventLocked(currentTime, entry, {target});
1601}
1602
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001603void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001604#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001605 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001606 ", policyFlags=0x%x, "
1607 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1608 "metaState=0x%x, buttonState=0x%x,"
1609 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001610 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1611 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1612 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001613
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001614 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001615 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001616 "x=%f, y=%f, pressure=%f, size=%f, "
1617 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1618 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001619 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1620 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1621 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1622 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1623 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1624 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1625 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1626 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1627 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1628 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001629 }
1630#endif
1631}
1632
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001633void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1634 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001635 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001636 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001637#if DEBUG_DISPATCH_CYCLE
1638 ALOGD("dispatchEventToCurrentInputTargets");
1639#endif
1640
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001641 updateInteractionTokensLocked(*eventEntry, inputTargets);
1642
Michael Wrightd02c5b62014-02-10 15:10:22 -08001643 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1644
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001645 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001646
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001647 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001648 sp<Connection> connection =
1649 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001650 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001651 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001652 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001653 if (DEBUG_FOCUS) {
1654 ALOGD("Dropping event delivery to target with channel '%s' because it "
1655 "is no longer registered with the input dispatcher.",
1656 inputTarget.inputChannel->getName().c_str());
1657 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001658 }
1659 }
1660}
1661
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001662void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1663 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1664 // If the policy decides to close the app, we will get a channel removal event via
1665 // unregisterInputChannel, and will clean up the connection that way. We are already not
1666 // sending new pointers to the connection when it blocked, but focused events will continue to
1667 // pile up.
1668 ALOGW("Canceling events for %s because it is unresponsive",
1669 connection->inputChannel->getName().c_str());
1670 if (connection->status == Connection::STATUS_NORMAL) {
1671 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1672 "application not responding");
1673 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001674 }
1675}
1676
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001677void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001678 if (DEBUG_FOCUS) {
1679 ALOGD("Resetting ANR timeouts.");
1680 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001681
1682 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001683 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001684 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001685}
1686
Tiger Huang721e26f2018-07-24 22:26:19 +08001687/**
1688 * Get the display id that the given event should go to. If this event specifies a valid display id,
1689 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1690 * Focused display is the display that the user most recently interacted with.
1691 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001692int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001693 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001694 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001695 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001696 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1697 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001698 break;
1699 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001700 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001701 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1702 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001703 break;
1704 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001705 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001706 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001707 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001708 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001709 case EventEntry::Type::SENSOR:
1710 case EventEntry::Type::DRAG: {
Chris Yef59a2f42020-10-16 12:55:26 -07001711 ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001712 return ADISPLAY_ID_NONE;
1713 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001714 }
1715 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1716}
1717
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001718bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1719 const char* focusedWindowName) {
1720 if (mAnrTracker.empty()) {
1721 // already processed all events that we waited for
1722 mKeyIsWaitingForEventsTimeout = std::nullopt;
1723 return false;
1724 }
1725
1726 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1727 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001728 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001729 mKeyIsWaitingForEventsTimeout = currentTime +
1730 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1731 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001732 return true;
1733 }
1734
1735 // We still have pending events, and already started the timer
1736 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1737 return true; // Still waiting
1738 }
1739
1740 // Waited too long, and some connection still hasn't processed all motions
1741 // Just send the key to the focused window
1742 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1743 focusedWindowName);
1744 mKeyIsWaitingForEventsTimeout = std::nullopt;
1745 return false;
1746}
1747
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001748InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1749 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1750 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001751 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001752
Tiger Huang721e26f2018-07-24 22:26:19 +08001753 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001754 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001755 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001756 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1757
Michael Wrightd02c5b62014-02-10 15:10:22 -08001758 // If there is no currently focused window and no focused application
1759 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001760 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1761 ALOGI("Dropping %s event because there is no focused window or focused application in "
1762 "display %" PRId32 ".",
Chris Yef59a2f42020-10-16 12:55:26 -07001763 NamedEnum::string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001764 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001765 }
1766
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001767 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1768 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1769 // start interacting with another application via touch (app switch). This code can be removed
1770 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1771 // an app is expected to have a focused window.
1772 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1773 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1774 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001775 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1776 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1777 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001778 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001779 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001780 ALOGW("Waiting because no window has focus but %s may eventually add a "
1781 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001782 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001783 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001784 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001785 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1786 // Already raised ANR. Drop the event
1787 ALOGE("Dropping %s event because there is no focused window",
Chris Yef59a2f42020-10-16 12:55:26 -07001788 NamedEnum::string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001789 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001790 } else {
1791 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001792 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001793 }
1794 }
1795
1796 // we have a valid, non-null focused window
1797 resetNoFocusedWindowTimeoutLocked();
1798
Michael Wrightd02c5b62014-02-10 15:10:22 -08001799 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001800 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001801 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001802 }
1803
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001804 if (focusedWindowHandle->getInfo()->paused) {
1805 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001806 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001807 }
1808
1809 // If the event is a key event, then we must wait for all previous events to
1810 // complete before delivering it because previous events may have the
1811 // side-effect of transferring focus to a different window and we want to
1812 // ensure that the following keys are sent to the new window.
1813 //
1814 // Suppose the user touches a button in a window then immediately presses "A".
1815 // If the button causes a pop-up window to appear then we want to ensure that
1816 // the "A" key is delivered to the new pop-up window. This is because users
1817 // often anticipate pending UI changes when typing on a keyboard.
1818 // To obtain this behavior, we must serialize key events with respect to all
1819 // prior input events.
1820 if (entry.type == EventEntry::Type::KEY) {
1821 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1822 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001823 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001824 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001825 }
1826
1827 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001828 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001829 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1830 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001831
1832 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001833 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001834}
1835
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001836/**
1837 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1838 * that are currently unresponsive.
1839 */
1840std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1841 const std::vector<TouchedMonitor>& monitors) const {
1842 std::vector<TouchedMonitor> responsiveMonitors;
1843 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1844 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1845 sp<Connection> connection = getConnectionLocked(
1846 monitor.monitor.inputChannel->getConnectionToken());
1847 if (connection == nullptr) {
1848 ALOGE("Could not find connection for monitor %s",
1849 monitor.monitor.inputChannel->getName().c_str());
1850 return false;
1851 }
1852 if (!connection->responsive) {
1853 ALOGW("Unresponsive monitor %s will not get the new gesture",
1854 connection->inputChannel->getName().c_str());
1855 return false;
1856 }
1857 return true;
1858 });
1859 return responsiveMonitors;
1860}
1861
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001862InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1863 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1864 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001865 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001866 enum InjectionPermission {
1867 INJECTION_PERMISSION_UNKNOWN,
1868 INJECTION_PERMISSION_GRANTED,
1869 INJECTION_PERMISSION_DENIED
1870 };
1871
Michael Wrightd02c5b62014-02-10 15:10:22 -08001872 // For security reasons, we defer updating the touch state until we are sure that
1873 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001874 int32_t displayId = entry.displayId;
1875 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001876 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1877
1878 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001879 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001880 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001881 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1882 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001883
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001884 // Copy current touch state into tempTouchState.
1885 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1886 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001887 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001888 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001889 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1890 mTouchStatesByDisplay.find(displayId);
1891 if (oldStateIt != mTouchStatesByDisplay.end()) {
1892 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001893 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001894 }
1895
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001896 bool isSplit = tempTouchState.split;
1897 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1898 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1899 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001900 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1901 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1902 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1903 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1904 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001905 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001906 bool wrongDevice = false;
1907 if (newGesture) {
1908 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001909 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001910 ALOGI("Dropping event because a pointer for a different device is already down "
1911 "in display %" PRId32,
1912 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001913 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001914 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001915 switchedDevice = false;
1916 wrongDevice = true;
1917 goto Failed;
1918 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001919 tempTouchState.reset();
1920 tempTouchState.down = down;
1921 tempTouchState.deviceId = entry.deviceId;
1922 tempTouchState.source = entry.source;
1923 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001924 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001925 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001926 ALOGI("Dropping move event because a pointer for a different device is already active "
1927 "in display %" PRId32,
1928 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001929 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001930 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001931 switchedDevice = false;
1932 wrongDevice = true;
1933 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001934 }
1935
1936 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1937 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1938
Garfield Tan00f511d2019-06-12 16:55:40 -07001939 int32_t x;
1940 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001941 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001942 // Always dispatch mouse events to cursor position.
1943 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001944 x = int32_t(entry.xCursorPosition);
1945 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001946 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001947 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1948 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001949 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001950 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001951 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001952 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1953 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001954
1955 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001956 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001957 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001958
Michael Wrightd02c5b62014-02-10 15:10:22 -08001959 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001960 if (newTouchedWindowHandle != nullptr &&
1961 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001962 // New window supports splitting, but we should never split mouse events.
1963 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001964 } else if (isSplit) {
1965 // New window does not support splitting but we have already split events.
1966 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001967 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001968 }
1969
1970 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001971 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001972 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001973 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001974 }
1975
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001976 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1977 ALOGI("Not sending touch event to %s because it is paused",
1978 newTouchedWindowHandle->getName().c_str());
1979 newTouchedWindowHandle = nullptr;
1980 }
1981
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001982 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001983 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001984 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1985 if (!isResponsive) {
1986 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001987 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1988 newTouchedWindowHandle = nullptr;
1989 }
1990 }
1991
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001992 // Drop events that can't be trusted due to occlusion
1993 if (newTouchedWindowHandle != nullptr &&
1994 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1995 TouchOcclusionInfo occlusionInfo =
1996 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001997 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001998 if (DEBUG_TOUCH_OCCLUSION) {
1999 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2000 for (const auto& log : occlusionInfo.debugInfo) {
2001 ALOGD("%s", log.c_str());
2002 }
2003 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002004 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
2005 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2006 ALOGW("Dropping untrusted touch event due to %s/%d",
2007 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2008 newTouchedWindowHandle = nullptr;
2009 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002010 }
2011 }
2012
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002013 // Also don't send the new touch event to unresponsive gesture monitors
2014 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
2015
Michael Wright3dd60e22019-03-27 22:06:44 +00002016 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
2017 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002018 "(%d, %d) in display %" PRId32 ".",
2019 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002020 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00002021 goto Failed;
2022 }
2023
2024 if (newTouchedWindowHandle != nullptr) {
2025 // Set target flags.
2026 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
2027 if (isSplit) {
2028 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002029 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002030 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2031 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2032 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2033 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2034 }
2035
2036 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07002037 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2038 newHoverWindowHandle = nullptr;
2039 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002040 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002041 }
2042
2043 // Update the temporary touch state.
2044 BitSet32 pointerIds;
2045 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002046 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002047 pointerIds.markBit(pointerId);
2048 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002049 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002050 }
2051
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002052 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002053 } else {
2054 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2055
2056 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002057 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002058 if (DEBUG_FOCUS) {
2059 ALOGD("Dropping event because the pointer is not down or we previously "
2060 "dropped the pointer down event in display %" PRId32,
2061 displayId);
2062 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002063 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002064 goto Failed;
2065 }
2066
arthurhung6d4bed92021-03-17 11:59:33 +08002067 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002068
Michael Wrightd02c5b62014-02-10 15:10:22 -08002069 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002070 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002071 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002072 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2073 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002074
2075 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002076 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002077 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002078 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2079 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002080 if (DEBUG_FOCUS) {
2081 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2082 oldTouchedWindowHandle->getName().c_str(),
2083 newTouchedWindowHandle->getName().c_str(), displayId);
2084 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002085 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002086 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2087 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2088 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002089
2090 // Make a slippery entrance into the new window.
2091 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2092 isSplit = true;
2093 }
2094
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002095 int32_t targetFlags =
2096 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002097 if (isSplit) {
2098 targetFlags |= InputTarget::FLAG_SPLIT;
2099 }
2100 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2101 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002102 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2103 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002104 }
2105
2106 BitSet32 pointerIds;
2107 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002108 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002109 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002110 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002111 }
2112 }
2113 }
2114
2115 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002116 // Let the previous window know that the hover sequence is over, unless we already did it
2117 // when dispatching it as is to newTouchedWindowHandle.
2118 if (mLastHoverWindowHandle != nullptr &&
2119 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2120 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002121#if DEBUG_HOVER
2122 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002123 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002124#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002125 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2126 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002127 }
2128
Garfield Tandf26e862020-07-01 20:18:19 -07002129 // Let the new window know that the hover sequence is starting, unless we already did it
2130 // when dispatching it as is to newTouchedWindowHandle.
2131 if (newHoverWindowHandle != nullptr &&
2132 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2133 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002134#if DEBUG_HOVER
2135 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002136 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002137#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002138 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2139 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2140 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002141 }
2142 }
2143
2144 // Check permission to inject into all touched foreground windows and ensure there
2145 // is at least one touched foreground window.
2146 {
2147 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002148 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002149 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2150 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002151 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002152 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002153 injectionPermission = INJECTION_PERMISSION_DENIED;
2154 goto Failed;
2155 }
2156 }
2157 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002158 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002159 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002160 ALOGI("Dropping event because there is no touched foreground window in display "
2161 "%" PRId32 " or gesture monitor to receive it.",
2162 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002163 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002164 goto Failed;
2165 }
2166
2167 // Permission granted to injection into all touched foreground windows.
2168 injectionPermission = INJECTION_PERMISSION_GRANTED;
2169 }
2170
2171 // Check whether windows listening for outside touches are owned by the same UID. If it is
2172 // set the policy flag that we will not reveal coordinate information to this window.
2173 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2174 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002175 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002176 if (foregroundWindowHandle) {
2177 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002178 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002179 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2180 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
2181 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002182 tempTouchState.addOrUpdateWindow(inputWindowHandle,
2183 InputTarget::FLAG_ZERO_COORDS,
2184 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002185 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002186 }
2187 }
2188 }
2189 }
2190
Michael Wrightd02c5b62014-02-10 15:10:22 -08002191 // If this is the first pointer going down and the touched window has a wallpaper
2192 // then also add the touched wallpaper windows so they are locked in for the duration
2193 // of the touch gesture.
2194 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2195 // engine only supports touch events. We would need to add a mechanism similar
2196 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2197 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2198 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002199 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002200 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07002201 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002202 getWindowHandlesLocked(displayId);
2203 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002204 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002205 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01002206 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002207 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002208 .addOrUpdateWindow(windowHandle,
2209 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2210 InputTarget::
2211 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2212 InputTarget::FLAG_DISPATCH_AS_IS,
2213 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002214 }
2215 }
2216 }
2217 }
2218
2219 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002220 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002221
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002222 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002223 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002224 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002225 }
2226
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002227 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002228 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002229 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002230 }
2231
Michael Wrightd02c5b62014-02-10 15:10:22 -08002232 // Drop the outside or hover touch windows since we will not care about them
2233 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002234 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002235
2236Failed:
2237 // Check injection permission once and for all.
2238 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002239 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002240 injectionPermission = INJECTION_PERMISSION_GRANTED;
2241 } else {
2242 injectionPermission = INJECTION_PERMISSION_DENIED;
2243 }
2244 }
2245
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002246 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2247 return injectionResult;
2248 }
2249
Michael Wrightd02c5b62014-02-10 15:10:22 -08002250 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002251 if (!wrongDevice) {
2252 if (switchedDevice) {
2253 if (DEBUG_FOCUS) {
2254 ALOGD("Conflicting pointer actions: Switched to a different device.");
2255 }
2256 *outConflictingPointerActions = true;
2257 }
2258
2259 if (isHoverAction) {
2260 // Started hovering, therefore no longer down.
2261 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002262 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002263 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2264 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002265 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002266 *outConflictingPointerActions = true;
2267 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002268 tempTouchState.reset();
2269 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2270 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2271 tempTouchState.deviceId = entry.deviceId;
2272 tempTouchState.source = entry.source;
2273 tempTouchState.displayId = displayId;
2274 }
2275 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2276 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2277 // All pointers up or canceled.
2278 tempTouchState.reset();
2279 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2280 // First pointer went down.
2281 if (oldState && oldState->down) {
2282 if (DEBUG_FOCUS) {
2283 ALOGD("Conflicting pointer actions: Down received while already down.");
2284 }
2285 *outConflictingPointerActions = true;
2286 }
2287 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2288 // One pointer went up.
2289 if (isSplit) {
2290 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2291 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002292
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002293 for (size_t i = 0; i < tempTouchState.windows.size();) {
2294 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2295 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2296 touchedWindow.pointerIds.clearBit(pointerId);
2297 if (touchedWindow.pointerIds.isEmpty()) {
2298 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2299 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002300 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002301 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002302 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002303 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002304 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002305 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002306
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002307 // Save changes unless the action was scroll in which case the temporary touch
2308 // state was only valid for this one action.
2309 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2310 if (tempTouchState.displayId >= 0) {
2311 mTouchStatesByDisplay[displayId] = tempTouchState;
2312 } else {
2313 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002314 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002315 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002316
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002317 // Update hover state.
2318 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002319 }
2320
Michael Wrightd02c5b62014-02-10 15:10:22 -08002321 return injectionResult;
2322}
2323
arthurhung6d4bed92021-03-17 11:59:33 +08002324void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
2325 const sp<InputWindowHandle> dropWindow =
2326 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
2327 false /*addOutsideTargets*/, false /*addPortalWindows*/,
2328 true /*ignoreDragWindow*/);
2329 if (dropWindow) {
2330 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
2331 notifyDropWindowLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002332 } else {
2333 notifyDropWindowLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002334 }
2335 mDragState.reset();
2336}
2337
2338void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2339 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002340 return;
2341 }
2342
arthurhung6d4bed92021-03-17 11:59:33 +08002343 if (!mDragState->isStartDrag) {
2344 mDragState->isStartDrag = true;
2345 mDragState->isStylusButtonDownAtStart =
2346 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2347 }
2348
arthurhungb89ccb02020-12-30 16:19:01 +08002349 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2350 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2351 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2352 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002353 // Handle the special case : stylus button no longer pressed.
2354 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2355 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2356 finishDragAndDrop(entry.displayId, x, y);
2357 return;
2358 }
2359
arthurhungb89ccb02020-12-30 16:19:01 +08002360 const sp<InputWindowHandle> hoverWindowHandle =
arthurhung6d4bed92021-03-17 11:59:33 +08002361 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
arthurhungb89ccb02020-12-30 16:19:01 +08002362 false /*addOutsideTargets*/, false /*addPortalWindows*/,
2363 true /*ignoreDragWindow*/);
2364 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002365 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2366 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2367 if (mDragState->dragHoverWindowHandle != nullptr) {
2368 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2369 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002370 }
arthurhung6d4bed92021-03-17 11:59:33 +08002371 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002372 }
2373 // enqueue drag location if needed.
2374 if (hoverWindowHandle != nullptr) {
2375 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2376 }
arthurhung6d4bed92021-03-17 11:59:33 +08002377 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2378 finishDragAndDrop(entry.displayId, x, y);
2379 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Arthur Hung6d0571e2021-04-09 20:18:16 +08002380 notifyDropWindowLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002381 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002382 }
2383}
2384
Michael Wrightd02c5b62014-02-10 15:10:22 -08002385void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002386 int32_t targetFlags, BitSet32 pointerIds,
2387 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002388 std::vector<InputTarget>::iterator it =
2389 std::find_if(inputTargets.begin(), inputTargets.end(),
2390 [&windowHandle](const InputTarget& inputTarget) {
2391 return inputTarget.inputChannel->getConnectionToken() ==
2392 windowHandle->getToken();
2393 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002394
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002395 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002396
2397 if (it == inputTargets.end()) {
2398 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002399 std::shared_ptr<InputChannel> inputChannel =
2400 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002401 if (inputChannel == nullptr) {
2402 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2403 return;
2404 }
2405 inputTarget.inputChannel = inputChannel;
2406 inputTarget.flags = targetFlags;
2407 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Evan Rosky84f07f02021-04-16 10:42:42 -07002408 inputTarget.displaySize =
2409 vec2(windowHandle->getInfo()->displayWidth, windowHandle->getInfo()->displayHeight);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002410 inputTargets.push_back(inputTarget);
2411 it = inputTargets.end() - 1;
2412 }
2413
2414 ALOG_ASSERT(it->flags == targetFlags);
2415 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2416
chaviw1ff3d1e2020-07-01 15:53:47 -07002417 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002418}
2419
Michael Wright3dd60e22019-03-27 22:06:44 +00002420void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002421 int32_t displayId, float xOffset,
2422 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002423 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2424 mGlobalMonitorsByDisplay.find(displayId);
2425
2426 if (it != mGlobalMonitorsByDisplay.end()) {
2427 const std::vector<Monitor>& monitors = it->second;
2428 for (const Monitor& monitor : monitors) {
2429 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002430 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002431 }
2432}
2433
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002434void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2435 float yOffset,
2436 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002437 InputTarget target;
2438 target.inputChannel = monitor.inputChannel;
2439 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002440 ui::Transform t;
2441 t.set(xOffset, yOffset);
2442 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002443 inputTargets.push_back(target);
2444}
2445
Michael Wrightd02c5b62014-02-10 15:10:22 -08002446bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002447 const InjectionState* injectionState) {
2448 if (injectionState &&
2449 (windowHandle == nullptr ||
2450 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2451 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002452 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002453 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002454 "owned by uid %d",
2455 injectionState->injectorPid, injectionState->injectorUid,
2456 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002457 } else {
2458 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002459 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002460 }
2461 return false;
2462 }
2463 return true;
2464}
2465
Robert Carrc9bf1d32020-04-13 17:21:08 -07002466/**
2467 * Indicate whether one window handle should be considered as obscuring
2468 * another window handle. We only check a few preconditions. Actually
2469 * checking the bounds is left to the caller.
2470 */
2471static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2472 const sp<InputWindowHandle>& otherHandle) {
2473 // Compare by token so cloned layers aren't counted
2474 if (haveSameToken(windowHandle, otherHandle)) {
2475 return false;
2476 }
2477 auto info = windowHandle->getInfo();
2478 auto otherInfo = otherHandle->getInfo();
2479 if (!otherInfo->visible) {
2480 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002481 } else if (otherInfo->alpha == 0 &&
2482 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2483 // Those act as if they were invisible, so we don't need to flag them.
2484 // We do want to potentially flag touchable windows even if they have 0
2485 // opacity, since they can consume touches and alter the effects of the
2486 // user interaction (eg. apps that rely on
2487 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2488 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2489 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002490 } else if (info->ownerUid == otherInfo->ownerUid) {
2491 // If ownerUid is the same we don't generate occlusion events as there
2492 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002493 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002494 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002495 return false;
2496 } else if (otherInfo->displayId != info->displayId) {
2497 return false;
2498 }
2499 return true;
2500}
2501
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002502/**
2503 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2504 * untrusted, one should check:
2505 *
2506 * 1. If result.hasBlockingOcclusion is true.
2507 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2508 * BLOCK_UNTRUSTED.
2509 *
2510 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2511 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2512 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2513 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2514 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2515 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2516 *
2517 * If neither of those is true, then it means the touch can be allowed.
2518 */
2519InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2520 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002521 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2522 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002523 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2524 TouchOcclusionInfo info;
2525 info.hasBlockingOcclusion = false;
2526 info.obscuringOpacity = 0;
2527 info.obscuringUid = -1;
2528 std::map<int32_t, float> opacityByUid;
2529 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2530 if (windowHandle == otherHandle) {
2531 break; // All future windows are below us. Exit early.
2532 }
2533 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002534 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2535 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002536 if (DEBUG_TOUCH_OCCLUSION) {
2537 info.debugInfo.push_back(
2538 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2539 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002540 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2541 // we perform the checks below to see if the touch can be propagated or not based on the
2542 // window's touch occlusion mode
2543 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2544 info.hasBlockingOcclusion = true;
2545 info.obscuringUid = otherInfo->ownerUid;
2546 info.obscuringPackage = otherInfo->packageName;
2547 break;
2548 }
2549 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2550 uint32_t uid = otherInfo->ownerUid;
2551 float opacity =
2552 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2553 // Given windows A and B:
2554 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2555 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2556 opacityByUid[uid] = opacity;
2557 if (opacity > info.obscuringOpacity) {
2558 info.obscuringOpacity = opacity;
2559 info.obscuringUid = uid;
2560 info.obscuringPackage = otherInfo->packageName;
2561 }
2562 }
2563 }
2564 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002565 if (DEBUG_TOUCH_OCCLUSION) {
2566 info.debugInfo.push_back(
2567 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2568 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002569 return info;
2570}
2571
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002572std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2573 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002574 return StringPrintf(INDENT2
2575 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2576 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2577 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2578 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002579 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002580 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002581 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002582 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2583 info->frameTop, info->frameRight, info->frameBottom,
2584 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002585 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2586 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2587 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002588}
2589
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002590bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2591 if (occlusionInfo.hasBlockingOcclusion) {
2592 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2593 occlusionInfo.obscuringUid);
2594 return false;
2595 }
2596 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2597 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2598 "%.2f, maximum allowed = %.2f)",
2599 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2600 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2601 return false;
2602 }
2603 return true;
2604}
2605
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002606bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2607 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002608 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002609 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002610 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002611 if (windowHandle == otherHandle) {
2612 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002613 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002614 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002615 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002616 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002617 return true;
2618 }
2619 }
2620 return false;
2621}
2622
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002623bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2624 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002625 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002626 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002627 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002628 if (windowHandle == otherHandle) {
2629 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002630 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002631 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002632 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002633 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002634 return true;
2635 }
2636 }
2637 return false;
2638}
2639
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002640std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002641 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002642 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002643 if (applicationHandle != nullptr) {
2644 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002645 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002646 } else {
2647 return applicationHandle->getName();
2648 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002649 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002650 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002651 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002652 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002653 }
2654}
2655
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002656void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002657 if (eventEntry.type == EventEntry::Type::FOCUS ||
arthurhungb89ccb02020-12-30 16:19:01 +08002658 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED ||
2659 eventEntry.type == EventEntry::Type::DRAG) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002660 // Focus or pointer capture changed events are passed to apps, but do not represent user
2661 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002662 return;
2663 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002664 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002665 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002666 if (focusedWindowHandle != nullptr) {
2667 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002668 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002669#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002670 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002671#endif
2672 return;
2673 }
2674 }
2675
2676 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002677 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002678 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002679 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2680 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002681 return;
2682 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002683
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002684 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002685 eventType = USER_ACTIVITY_EVENT_TOUCH;
2686 }
2687 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002688 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002689 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002690 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2691 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002692 return;
2693 }
2694 eventType = USER_ACTIVITY_EVENT_BUTTON;
2695 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002696 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002697 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002698 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002699 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002700 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08002701 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2702 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002703 LOG_ALWAYS_FATAL("%s events are not user activity",
Chris Yef59a2f42020-10-16 12:55:26 -07002704 NamedEnum::string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002705 break;
2706 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002707 }
2708
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002709 std::unique_ptr<CommandEntry> commandEntry =
2710 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002711 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002712 commandEntry->userActivityEventType = eventType;
Sean Stoutb4e0a592021-02-23 07:34:53 -08002713 commandEntry->displayId = displayId;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002714 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002715}
2716
2717void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002718 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002719 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002720 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002721 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002722 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002723 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002724 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002725 ATRACE_NAME(message.c_str());
2726 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002727#if DEBUG_DISPATCH_CYCLE
2728 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002729 "globalScaleFactor=%f, pointerIds=0x%x %s",
2730 connection->getInputChannelName().c_str(), inputTarget.flags,
2731 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2732 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002733#endif
2734
2735 // Skip this event if the connection status is not normal.
2736 // We don't want to enqueue additional outbound events if the connection is broken.
2737 if (connection->status != Connection::STATUS_NORMAL) {
2738#if DEBUG_DISPATCH_CYCLE
2739 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002740 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002741#endif
2742 return;
2743 }
2744
2745 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002746 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2747 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2748 "Entry type %s should not have FLAG_SPLIT",
Chris Yef59a2f42020-10-16 12:55:26 -07002749 NamedEnum::string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002750
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002751 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002752 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002753 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002754 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002755 if (!splitMotionEntry) {
2756 return; // split event was dropped
2757 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002758 if (DEBUG_FOCUS) {
2759 ALOGD("channel '%s' ~ Split motion event.",
2760 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002761 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002762 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002763 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2764 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002765 return;
2766 }
2767 }
2768
2769 // Not splitting. Enqueue dispatch entries for the event as is.
2770 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2771}
2772
2773void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002774 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002775 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002776 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002777 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002778 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002779 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002780 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002781 ATRACE_NAME(message.c_str());
2782 }
2783
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002784 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002785
2786 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002787 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002788 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002789 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002790 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002791 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002792 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002793 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002794 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002795 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002796 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002797 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002798 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002799
2800 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002801 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002802 startDispatchCycleLocked(currentTime, connection);
2803 }
2804}
2805
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002806void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002807 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002808 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002809 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002810 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002811 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2812 connection->getInputChannelName().c_str(),
2813 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002814 ATRACE_NAME(message.c_str());
2815 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002816 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002817 if (!(inputTargetFlags & dispatchMode)) {
2818 return;
2819 }
2820 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2821
2822 // This is a new event.
2823 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002824 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002825 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002826
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002827 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2828 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002829 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002830 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002831 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002832 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002833 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002834 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002835 dispatchEntry->resolvedAction = keyEntry.action;
2836 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002837
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002838 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2839 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002840#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002841 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2842 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002843#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002844 return; // skip the inconsistent event
2845 }
2846 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002847 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002848
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002849 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002850 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002851 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2852 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2853 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2854 static_cast<int32_t>(IdGenerator::Source::OTHER);
2855 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002856 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2857 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2858 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2859 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2860 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2861 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2862 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2863 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2864 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2865 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2866 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002867 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002868 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002869 }
2870 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002871 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2872 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002873#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002874 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2875 "event",
2876 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002877#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002878 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2879 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002880
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002881 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002882 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2883 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2884 }
2885 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2886 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2887 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002888
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002889 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2890 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002891#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002892 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2893 "event",
2894 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002895#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002896 return; // skip the inconsistent event
2897 }
2898
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002899 dispatchEntry->resolvedEventId =
2900 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2901 ? mIdGenerator.nextId()
2902 : motionEntry.id;
2903 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2904 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2905 ") to MotionEvent(id=0x%" PRIx32 ").",
2906 motionEntry.id, dispatchEntry->resolvedEventId);
2907 ATRACE_NAME(message.c_str());
2908 }
2909
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08002910 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
2911 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
2912 // Skip reporting pointer down outside focus to the policy.
2913 break;
2914 }
2915
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002916 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002917 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002918
2919 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002920 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002921 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08002922 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2923 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002924 break;
2925 }
Chris Yef59a2f42020-10-16 12:55:26 -07002926 case EventEntry::Type::SENSOR: {
2927 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
2928 break;
2929 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002930 case EventEntry::Type::CONFIGURATION_CHANGED:
2931 case EventEntry::Type::DEVICE_RESET: {
2932 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chris Yef59a2f42020-10-16 12:55:26 -07002933 NamedEnum::string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002934 break;
2935 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002936 }
2937
2938 // Remember that we are waiting for this dispatch to complete.
2939 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002940 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002941 }
2942
2943 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002944 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002945 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002946}
2947
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002948/**
2949 * This function is purely for debugging. It helps us understand where the user interaction
2950 * was taking place. For example, if user is touching launcher, we will see a log that user
2951 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2952 * We will see both launcher and wallpaper in that list.
2953 * Once the interaction with a particular set of connections starts, no new logs will be printed
2954 * until the set of interacted connections changes.
2955 *
2956 * The following items are skipped, to reduce the logspam:
2957 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2958 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2959 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2960 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2961 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002962 */
2963void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2964 const std::vector<InputTarget>& targets) {
2965 // Skip ACTION_UP events, and all events other than keys and motions
2966 if (entry.type == EventEntry::Type::KEY) {
2967 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2968 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2969 return;
2970 }
2971 } else if (entry.type == EventEntry::Type::MOTION) {
2972 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2973 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2974 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2975 return;
2976 }
2977 } else {
2978 return; // Not a key or a motion
2979 }
2980
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07002981 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002982 std::vector<sp<Connection>> newConnections;
2983 for (const InputTarget& target : targets) {
2984 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2985 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2986 continue; // Skip windows that receive ACTION_OUTSIDE
2987 }
2988
2989 sp<IBinder> token = target.inputChannel->getConnectionToken();
2990 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002991 if (connection == nullptr) {
2992 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002993 }
2994 newConnectionTokens.insert(std::move(token));
2995 newConnections.emplace_back(connection);
2996 }
2997 if (newConnectionTokens == mInteractionConnectionTokens) {
2998 return; // no change
2999 }
3000 mInteractionConnectionTokens = newConnectionTokens;
3001
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003002 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003003 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003004 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003005 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003006 std::string message = "Interaction with: " + targetList;
3007 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003008 message += "<none>";
3009 }
3010 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3011}
3012
chaviwfd6d3512019-03-25 13:23:49 -07003013void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003014 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003015 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003016 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3017 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003018 return;
3019 }
3020
Vishnu Nairc519ff72021-01-21 08:23:08 -08003021 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003022 if (focusedToken == token) {
3023 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003024 return;
3025 }
3026
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07003027 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
3028 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003029 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07003030 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003031}
3032
3033void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003034 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003035 if (ATRACE_ENABLED()) {
3036 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003037 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003038 ATRACE_NAME(message.c_str());
3039 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003040#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003041 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003042#endif
3043
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003044 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3045 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003046 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003047 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003048 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003049 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003050
3051 // Publish the event.
3052 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003053 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3054 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003055 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003056 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3057 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003058
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003059 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003060 status = connection->inputPublisher
3061 .publishKeyEvent(dispatchEntry->seq,
3062 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3063 keyEntry.source, keyEntry.displayId,
3064 std::move(hmac), dispatchEntry->resolvedAction,
3065 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3066 keyEntry.scanCode, keyEntry.metaState,
3067 keyEntry.repeatCount, keyEntry.downTime,
3068 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003069 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003070 }
3071
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003072 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003073 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003074
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003075 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003076 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003077
chaviw82357092020-01-28 13:13:06 -08003078 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003079 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003080 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3081 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003082 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003083 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3084 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003085 // Don't apply window scale here since we don't want scale to affect raw
3086 // coordinates. The scale will be sent back to the client and applied
3087 // later when requesting relative coordinates.
3088 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3089 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003090 }
3091 usingCoords = scaledCoords;
3092 }
3093 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003094 // We don't want the dispatch target to know.
3095 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003096 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003097 scaledCoords[i].clear();
3098 }
3099 usingCoords = scaledCoords;
3100 }
3101 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003102
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003103 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003104
3105 // Publish the motion event.
3106 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003107 .publishMotionEvent(dispatchEntry->seq,
3108 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003109 motionEntry.deviceId, motionEntry.source,
3110 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003111 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003112 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003113 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003114 motionEntry.edgeFlags, motionEntry.metaState,
3115 motionEntry.buttonState,
3116 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003117 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003118 motionEntry.xPrecision, motionEntry.yPrecision,
3119 motionEntry.xCursorPosition,
3120 motionEntry.yCursorPosition,
Evan Rosky84f07f02021-04-16 10:42:42 -07003121 dispatchEntry->displaySize.x,
3122 dispatchEntry->displaySize.y,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003123 motionEntry.downTime, motionEntry.eventTime,
3124 motionEntry.pointerCount,
3125 motionEntry.pointerProperties, usingCoords);
3126 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003127 break;
3128 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003129
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003130 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003131 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003132 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003133 focusEntry.id,
3134 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003135 mInTouchMode);
3136 break;
3137 }
3138
Prabir Pradhan99987712020-11-10 18:43:05 -08003139 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3140 const auto& captureEntry =
3141 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3142 status = connection->inputPublisher
3143 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
3144 captureEntry.pointerCaptureEnabled);
3145 break;
3146 }
3147
arthurhungb89ccb02020-12-30 16:19:01 +08003148 case EventEntry::Type::DRAG: {
3149 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3150 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3151 dragEntry.id, dragEntry.x,
3152 dragEntry.y,
3153 dragEntry.isExiting);
3154 break;
3155 }
3156
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003157 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003158 case EventEntry::Type::DEVICE_RESET:
3159 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003160 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Chris Yef59a2f42020-10-16 12:55:26 -07003161 NamedEnum::string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003162 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003163 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003164 }
3165
3166 // Check the result.
3167 if (status) {
3168 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003169 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003170 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003171 "This is unexpected because the wait queue is empty, so the pipe "
3172 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003173 "event to it, status=%s(%d)",
3174 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3175 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003176 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3177 } else {
3178 // Pipe is full and we are waiting for the app to finish process some events
3179 // before sending more events to it.
3180#if DEBUG_DISPATCH_CYCLE
3181 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003182 "waiting for the application to catch up",
3183 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003184#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003185 }
3186 } else {
3187 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003188 "status=%s(%d)",
3189 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3190 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003191 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3192 }
3193 return;
3194 }
3195
3196 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003197 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3198 connection->outboundQueue.end(),
3199 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003200 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003201 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003202 if (connection->responsive) {
3203 mAnrTracker.insert(dispatchEntry->timeoutTime,
3204 connection->inputChannel->getConnectionToken());
3205 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003206 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003207 }
3208}
3209
chaviw09c8d2d2020-08-24 15:48:26 -07003210std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3211 size_t size;
3212 switch (event.type) {
3213 case VerifiedInputEvent::Type::KEY: {
3214 size = sizeof(VerifiedKeyEvent);
3215 break;
3216 }
3217 case VerifiedInputEvent::Type::MOTION: {
3218 size = sizeof(VerifiedMotionEvent);
3219 break;
3220 }
3221 }
3222 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3223 return mHmacKeyManager.sign(start, size);
3224}
3225
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003226const std::array<uint8_t, 32> InputDispatcher::getSignature(
3227 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3228 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3229 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3230 // Only sign events up and down events as the purely move events
3231 // are tied to their up/down counterparts so signing would be redundant.
3232 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3233 verifiedEvent.actionMasked = actionMasked;
3234 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003235 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003236 }
3237 return INVALID_HMAC;
3238}
3239
3240const std::array<uint8_t, 32> InputDispatcher::getSignature(
3241 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3242 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3243 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3244 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003245 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003246}
3247
Michael Wrightd02c5b62014-02-10 15:10:22 -08003248void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003249 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003250 bool handled, nsecs_t consumeTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003251#if DEBUG_DISPATCH_CYCLE
3252 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003253 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003254#endif
3255
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003256 if (connection->status == Connection::STATUS_BROKEN ||
3257 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003258 return;
3259 }
3260
3261 // Notify other system components and prepare to start the next dispatch cycle.
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003262 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled, consumeTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003263}
3264
3265void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003266 const sp<Connection>& connection,
3267 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003268#if DEBUG_DISPATCH_CYCLE
3269 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003270 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003271#endif
3272
3273 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003274 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003275 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003276 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003277 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003278
3279 // The connection appears to be unrecoverably broken.
3280 // Ignore already broken or zombie connections.
3281 if (connection->status == Connection::STATUS_NORMAL) {
3282 connection->status = Connection::STATUS_BROKEN;
3283
3284 if (notify) {
3285 // Notify other system components.
3286 onDispatchCycleBrokenLocked(currentTime, connection);
3287 }
3288 }
3289}
3290
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003291void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3292 while (!queue.empty()) {
3293 DispatchEntry* dispatchEntry = queue.front();
3294 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003295 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003296 }
3297}
3298
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003299void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003300 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003301 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003302 }
3303 delete dispatchEntry;
3304}
3305
3306int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
3307 InputDispatcher* d = static_cast<InputDispatcher*>(data);
3308
3309 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003310 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003311
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003312 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003313 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003314 "fd=%d, events=0x%x",
3315 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003316 return 0; // remove the callback
3317 }
3318
3319 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003320 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003321 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3322 if (!(events & ALOOPER_EVENT_INPUT)) {
3323 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003324 "events=0x%x",
3325 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003326 return 1;
3327 }
3328
3329 nsecs_t currentTime = now();
3330 bool gotOne = false;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00003331 status_t status = OK;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003332 for (;;) {
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +00003333 Result<InputPublisher::ConsumerResponse> result =
3334 connection->inputPublisher.receiveConsumerResponse();
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00003335 if (!result.ok()) {
3336 status = result.error().code();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003337 break;
3338 }
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +00003339
3340 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3341 const InputPublisher::Finished& finish =
3342 std::get<InputPublisher::Finished>(*result);
3343 d->finishDispatchCycleLocked(currentTime, connection, finish.seq,
3344 finish.handled, finish.consumeTime);
3345 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
3346 // TODO(b/167947340): Report this data to LatencyTracker
3347 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003348 gotOne = true;
3349 }
3350 if (gotOne) {
3351 d->runCommandsLockedInterruptible();
3352 if (status == WOULD_BLOCK) {
3353 return 1;
3354 }
3355 }
3356
3357 notify = status != DEAD_OBJECT || !connection->monitor;
3358 if (notify) {
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003359 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3360 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3361 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003362 }
3363 } else {
3364 // Monitor channels are never explicitly unregistered.
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003365 // We do it automatically when the remote endpoint is closed so don't warn about them.
arthurhungd352cb32020-04-28 17:09:28 +08003366 const bool stillHaveWindowHandle =
3367 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3368 nullptr;
3369 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003370 if (notify) {
3371 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003372 "events=0x%x",
3373 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003374 }
3375 }
3376
Garfield Tan15601662020-09-22 15:32:38 -07003377 // Remove the channel.
3378 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003379 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003380 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003381}
3382
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003383void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003384 const CancelationOptions& options) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003385 for (const auto& [fd, connection] : mConnectionsByFd) {
3386 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003387 }
3388}
3389
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003390void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003391 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003392 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3393 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3394}
3395
3396void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3397 const CancelationOptions& options,
3398 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3399 for (const auto& it : monitorsByDisplay) {
3400 const std::vector<Monitor>& monitors = it.second;
3401 for (const Monitor& monitor : monitors) {
3402 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003403 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003404 }
3405}
3406
Michael Wrightd02c5b62014-02-10 15:10:22 -08003407void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003408 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003409 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003410 if (connection == nullptr) {
3411 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003412 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003413
3414 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003415}
3416
3417void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3418 const sp<Connection>& connection, const CancelationOptions& options) {
3419 if (connection->status == Connection::STATUS_BROKEN) {
3420 return;
3421 }
3422
3423 nsecs_t currentTime = now();
3424
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003425 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003426 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003427
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003428 if (cancelationEvents.empty()) {
3429 return;
3430 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003431#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003432 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3433 "with reality: %s, mode=%d.",
3434 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3435 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003436#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003437
3438 InputTarget target;
3439 sp<InputWindowHandle> windowHandle =
3440 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3441 if (windowHandle != nullptr) {
3442 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003443 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003444 target.globalScaleFactor = windowInfo->globalScaleFactor;
3445 }
3446 target.inputChannel = connection->inputChannel;
3447 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3448
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003449 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003450 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003451 switch (cancelationEventEntry->type) {
3452 case EventEntry::Type::KEY: {
3453 logOutboundKeyDetails("cancel - ",
3454 static_cast<const KeyEntry&>(*cancelationEventEntry));
3455 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003456 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003457 case EventEntry::Type::MOTION: {
3458 logOutboundMotionDetails("cancel - ",
3459 static_cast<const MotionEntry&>(*cancelationEventEntry));
3460 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003461 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003462 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08003463 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3464 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003465 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Chris Yef59a2f42020-10-16 12:55:26 -07003466 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003467 break;
3468 }
3469 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003470 case EventEntry::Type::DEVICE_RESET:
3471 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003472 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003473 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003474 break;
3475 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003476 }
3477
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003478 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3479 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003480 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003481
3482 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003483}
3484
Svet Ganov5d3bc372020-01-26 23:11:07 -08003485void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3486 const sp<Connection>& connection) {
3487 if (connection->status == Connection::STATUS_BROKEN) {
3488 return;
3489 }
3490
3491 nsecs_t currentTime = now();
3492
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003493 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003494 connection->inputState.synthesizePointerDownEvents(currentTime);
3495
3496 if (downEvents.empty()) {
3497 return;
3498 }
3499
3500#if DEBUG_OUTBOUND_EVENT_DETAILS
3501 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3502 connection->getInputChannelName().c_str(), downEvents.size());
3503#endif
3504
3505 InputTarget target;
3506 sp<InputWindowHandle> windowHandle =
3507 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3508 if (windowHandle != nullptr) {
3509 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003510 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003511 target.globalScaleFactor = windowInfo->globalScaleFactor;
3512 }
3513 target.inputChannel = connection->inputChannel;
3514 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3515
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003516 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003517 switch (downEventEntry->type) {
3518 case EventEntry::Type::MOTION: {
3519 logOutboundMotionDetails("down - ",
3520 static_cast<const MotionEntry&>(*downEventEntry));
3521 break;
3522 }
3523
3524 case EventEntry::Type::KEY:
3525 case EventEntry::Type::FOCUS:
3526 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003527 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003528 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003529 case EventEntry::Type::SENSOR:
3530 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003531 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003532 NamedEnum::string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003533 break;
3534 }
3535 }
3536
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003537 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3538 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003539 }
3540
3541 startDispatchCycleLocked(currentTime, connection);
3542}
3543
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003544std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3545 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003546 ALOG_ASSERT(pointerIds.value != 0);
3547
3548 uint32_t splitPointerIndexMap[MAX_POINTERS];
3549 PointerProperties splitPointerProperties[MAX_POINTERS];
3550 PointerCoords splitPointerCoords[MAX_POINTERS];
3551
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003552 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003553 uint32_t splitPointerCount = 0;
3554
3555 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003556 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003557 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003558 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003559 uint32_t pointerId = uint32_t(pointerProperties.id);
3560 if (pointerIds.hasBit(pointerId)) {
3561 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3562 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3563 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003564 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003565 splitPointerCount += 1;
3566 }
3567 }
3568
3569 if (splitPointerCount != pointerIds.count()) {
3570 // This is bad. We are missing some of the pointers that we expected to deliver.
3571 // Most likely this indicates that we received an ACTION_MOVE events that has
3572 // different pointer ids than we expected based on the previous ACTION_DOWN
3573 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3574 // in this way.
3575 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003576 "we expected there to be %d pointers. This probably means we received "
3577 "a broken sequence of pointer ids from the input device.",
3578 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003579 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003580 }
3581
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003582 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003583 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003584 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3585 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003586 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3587 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003588 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003589 uint32_t pointerId = uint32_t(pointerProperties.id);
3590 if (pointerIds.hasBit(pointerId)) {
3591 if (pointerIds.count() == 1) {
3592 // The first/last pointer went down/up.
3593 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003594 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003595 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3596 ? AMOTION_EVENT_ACTION_CANCEL
3597 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003598 } else {
3599 // A secondary pointer went down/up.
3600 uint32_t splitPointerIndex = 0;
3601 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3602 splitPointerIndex += 1;
3603 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003604 action = maskedAction |
3605 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003606 }
3607 } else {
3608 // An unrelated pointer changed.
3609 action = AMOTION_EVENT_ACTION_MOVE;
3610 }
3611 }
3612
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003613 int32_t newId = mIdGenerator.nextId();
3614 if (ATRACE_ENABLED()) {
3615 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3616 ") to MotionEvent(id=0x%" PRIx32 ").",
3617 originalMotionEntry.id, newId);
3618 ATRACE_NAME(message.c_str());
3619 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003620 std::unique_ptr<MotionEntry> splitMotionEntry =
3621 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3622 originalMotionEntry.deviceId, originalMotionEntry.source,
3623 originalMotionEntry.displayId,
3624 originalMotionEntry.policyFlags, action,
3625 originalMotionEntry.actionButton,
3626 originalMotionEntry.flags, originalMotionEntry.metaState,
3627 originalMotionEntry.buttonState,
3628 originalMotionEntry.classification,
3629 originalMotionEntry.edgeFlags,
3630 originalMotionEntry.xPrecision,
3631 originalMotionEntry.yPrecision,
3632 originalMotionEntry.xCursorPosition,
3633 originalMotionEntry.yCursorPosition,
3634 originalMotionEntry.downTime, splitPointerCount,
3635 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003636
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003637 if (originalMotionEntry.injectionState) {
3638 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003639 splitMotionEntry->injectionState->refCount += 1;
3640 }
3641
3642 return splitMotionEntry;
3643}
3644
3645void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3646#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003647 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003648#endif
3649
3650 bool needWake;
3651 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003652 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003653
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003654 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3655 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3656 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003657 } // release lock
3658
3659 if (needWake) {
3660 mLooper->wake();
3661 }
3662}
3663
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003664/**
3665 * If one of the meta shortcuts is detected, process them here:
3666 * Meta + Backspace -> generate BACK
3667 * Meta + Enter -> generate HOME
3668 * This will potentially overwrite keyCode and metaState.
3669 */
3670void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003671 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003672 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3673 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3674 if (keyCode == AKEYCODE_DEL) {
3675 newKeyCode = AKEYCODE_BACK;
3676 } else if (keyCode == AKEYCODE_ENTER) {
3677 newKeyCode = AKEYCODE_HOME;
3678 }
3679 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003680 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003681 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003682 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003683 keyCode = newKeyCode;
3684 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3685 }
3686 } else if (action == AKEY_EVENT_ACTION_UP) {
3687 // In order to maintain a consistent stream of up and down events, check to see if the key
3688 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3689 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003690 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003691 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003692 auto replacementIt = mReplacedKeys.find(replacement);
3693 if (replacementIt != mReplacedKeys.end()) {
3694 keyCode = replacementIt->second;
3695 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003696 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3697 }
3698 }
3699}
3700
Michael Wrightd02c5b62014-02-10 15:10:22 -08003701void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3702#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003703 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3704 "policyFlags=0x%x, action=0x%x, "
3705 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3706 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3707 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3708 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003709#endif
3710 if (!validateKeyEvent(args->action)) {
3711 return;
3712 }
3713
3714 uint32_t policyFlags = args->policyFlags;
3715 int32_t flags = args->flags;
3716 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003717 // InputDispatcher tracks and generates key repeats on behalf of
3718 // whatever notifies it, so repeatCount should always be set to 0
3719 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003720 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3721 policyFlags |= POLICY_FLAG_VIRTUAL;
3722 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3723 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003724 if (policyFlags & POLICY_FLAG_FUNCTION) {
3725 metaState |= AMETA_FUNCTION_ON;
3726 }
3727
3728 policyFlags |= POLICY_FLAG_TRUSTED;
3729
Michael Wright78f24442014-08-06 15:55:28 -07003730 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003731 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003732
Michael Wrightd02c5b62014-02-10 15:10:22 -08003733 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003734 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003735 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3736 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003737
Michael Wright2b3c3302018-03-02 17:19:13 +00003738 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003739 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003740 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3741 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003742 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003743 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003744
Michael Wrightd02c5b62014-02-10 15:10:22 -08003745 bool needWake;
3746 { // acquire lock
3747 mLock.lock();
3748
3749 if (shouldSendKeyToInputFilterLocked(args)) {
3750 mLock.unlock();
3751
3752 policyFlags |= POLICY_FLAG_FILTERED;
3753 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3754 return; // event was consumed by the filter
3755 }
3756
3757 mLock.lock();
3758 }
3759
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003760 std::unique_ptr<KeyEntry> newEntry =
3761 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3762 args->displayId, policyFlags, args->action, flags,
3763 keyCode, args->scanCode, metaState, repeatCount,
3764 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003765
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003766 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003767 mLock.unlock();
3768 } // release lock
3769
3770 if (needWake) {
3771 mLooper->wake();
3772 }
3773}
3774
3775bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3776 return mInputFilterEnabled;
3777}
3778
3779void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3780#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003781 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3782 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003783 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3784 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003785 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003786 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3787 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3788 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3789 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003790 for (uint32_t i = 0; i < args->pointerCount; i++) {
3791 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003792 "x=%f, y=%f, pressure=%f, size=%f, "
3793 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3794 "orientation=%f",
3795 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3796 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3797 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3798 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3799 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3800 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3801 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3802 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3803 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3804 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003805 }
3806#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003807 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3808 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003809 return;
3810 }
3811
3812 uint32_t policyFlags = args->policyFlags;
3813 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003814
3815 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003816 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003817 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3818 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003819 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003820 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003821
3822 bool needWake;
3823 { // acquire lock
3824 mLock.lock();
3825
3826 if (shouldSendMotionToInputFilterLocked(args)) {
3827 mLock.unlock();
3828
3829 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003830 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003831 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3832 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003833 args->metaState, args->buttonState, args->classification, transform,
3834 args->xPrecision, args->yPrecision, args->xCursorPosition,
Evan Rosky84f07f02021-04-16 10:42:42 -07003835 args->yCursorPosition, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
3836 AMOTION_EVENT_INVALID_DISPLAY_SIZE, args->downTime, args->eventTime,
chaviw9eaa22c2020-07-01 16:21:27 -07003837 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003838
3839 policyFlags |= POLICY_FLAG_FILTERED;
3840 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3841 return; // event was consumed by the filter
3842 }
3843
3844 mLock.lock();
3845 }
3846
3847 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003848 std::unique_ptr<MotionEntry> newEntry =
3849 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3850 args->source, args->displayId, policyFlags,
3851 args->action, args->actionButton, args->flags,
3852 args->metaState, args->buttonState,
3853 args->classification, args->edgeFlags,
3854 args->xPrecision, args->yPrecision,
3855 args->xCursorPosition, args->yCursorPosition,
3856 args->downTime, args->pointerCount,
3857 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003858
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003859 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003860 mLock.unlock();
3861 } // release lock
3862
3863 if (needWake) {
3864 mLooper->wake();
3865 }
3866}
3867
Chris Yef59a2f42020-10-16 12:55:26 -07003868void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
3869#if DEBUG_INBOUND_EVENT_DETAILS
3870 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3871 " sensorType=%s",
3872 args->id, args->eventTime, args->deviceId, args->source,
3873 NamedEnum::string(args->sensorType).c_str());
3874#endif
3875
3876 bool needWake;
3877 { // acquire lock
3878 mLock.lock();
3879
3880 // Just enqueue a new sensor event.
3881 std::unique_ptr<SensorEntry> newEntry =
3882 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
3883 args->source, 0 /* policyFlags*/, args->hwTimestamp,
3884 args->sensorType, args->accuracy,
3885 args->accuracyChanged, args->values);
3886
3887 needWake = enqueueInboundEventLocked(std::move(newEntry));
3888 mLock.unlock();
3889 } // release lock
3890
3891 if (needWake) {
3892 mLooper->wake();
3893 }
3894}
3895
Chris Yefb552902021-02-03 17:18:37 -08003896void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
3897#if DEBUG_INBOUND_EVENT_DETAILS
3898 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
3899 args->deviceId, args->isOn);
3900#endif
3901 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
3902}
3903
Michael Wrightd02c5b62014-02-10 15:10:22 -08003904bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003905 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003906}
3907
3908void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3909#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003910 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003911 "switchMask=0x%08x",
3912 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003913#endif
3914
3915 uint32_t policyFlags = args->policyFlags;
3916 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003917 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003918}
3919
3920void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3921#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003922 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3923 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003924#endif
3925
3926 bool needWake;
3927 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003928 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003929
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003930 std::unique_ptr<DeviceResetEntry> newEntry =
3931 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3932 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003933 } // release lock
3934
3935 if (needWake) {
3936 mLooper->wake();
3937 }
3938}
3939
Prabir Pradhan7e186182020-11-10 13:56:45 -08003940void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3941#if DEBUG_INBOUND_EVENT_DETAILS
3942 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3943 args->enabled ? "true" : "false");
3944#endif
3945
Prabir Pradhan99987712020-11-10 18:43:05 -08003946 bool needWake;
3947 { // acquire lock
3948 std::scoped_lock _l(mLock);
3949 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
3950 args->enabled);
3951 needWake = enqueueInboundEventLocked(std::move(entry));
3952 } // release lock
3953
3954 if (needWake) {
3955 mLooper->wake();
3956 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003957}
3958
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003959InputEventInjectionResult InputDispatcher::injectInputEvent(
3960 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3961 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962#if DEBUG_INBOUND_EVENT_DETAILS
3963 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003964 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3965 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003966#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003967 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003968
3969 policyFlags |= POLICY_FLAG_INJECTED;
3970 if (hasInjectionPermission(injectorPid, injectorUid)) {
3971 policyFlags |= POLICY_FLAG_TRUSTED;
3972 }
3973
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003974 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003975 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003976 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003977 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3978 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003979 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003980 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003981 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003982
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003983 int32_t flags = incomingKey.getFlags();
3984 int32_t keyCode = incomingKey.getKeyCode();
3985 int32_t metaState = incomingKey.getMetaState();
3986 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003987 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003988 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003989 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003990 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3991 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3992 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003993
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003994 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3995 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003996 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003997
3998 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3999 android::base::Timer t;
4000 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4001 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4002 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4003 std::to_string(t.duration().count()).c_str());
4004 }
4005 }
4006
4007 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004008 std::unique_ptr<KeyEntry> injectedEntry =
4009 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
4010 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
4011 incomingKey.getDisplayId(), policyFlags, action,
4012 flags, keyCode, incomingKey.getScanCode(), metaState,
4013 incomingKey.getRepeatCount(),
4014 incomingKey.getDownTime());
4015 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004016 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004017 }
4018
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004019 case AINPUT_EVENT_TYPE_MOTION: {
4020 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
4021 int32_t action = motionEvent->getAction();
4022 size_t pointerCount = motionEvent->getPointerCount();
4023 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
4024 int32_t actionButton = motionEvent->getActionButton();
4025 int32_t displayId = motionEvent->getDisplayId();
4026 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004027 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004028 }
4029
4030 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4031 nsecs_t eventTime = motionEvent->getEventTime();
4032 android::base::Timer t;
4033 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4034 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4035 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4036 std::to_string(t.duration().count()).c_str());
4037 }
4038 }
4039
4040 mLock.lock();
4041 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
4042 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004043 std::unique_ptr<MotionEntry> injectedEntry =
4044 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
4045 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
4046 motionEvent->getDisplayId(), policyFlags, action,
4047 actionButton, motionEvent->getFlags(),
4048 motionEvent->getMetaState(),
4049 motionEvent->getButtonState(),
4050 motionEvent->getClassification(),
4051 motionEvent->getEdgeFlags(),
4052 motionEvent->getXPrecision(),
4053 motionEvent->getYPrecision(),
4054 motionEvent->getRawXCursorPosition(),
4055 motionEvent->getRawYCursorPosition(),
4056 motionEvent->getDownTime(),
4057 uint32_t(pointerCount), pointerProperties,
4058 samplePointerCoords, motionEvent->getXOffset(),
4059 motionEvent->getYOffset());
4060 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004061 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
4062 sampleEventTimes += 1;
4063 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004064 std::unique_ptr<MotionEntry> nextInjectedEntry =
4065 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
4066 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
4067 motionEvent->getDisplayId(), policyFlags,
4068 action, actionButton, motionEvent->getFlags(),
4069 motionEvent->getMetaState(),
4070 motionEvent->getButtonState(),
4071 motionEvent->getClassification(),
4072 motionEvent->getEdgeFlags(),
4073 motionEvent->getXPrecision(),
4074 motionEvent->getYPrecision(),
4075 motionEvent->getRawXCursorPosition(),
4076 motionEvent->getRawYCursorPosition(),
4077 motionEvent->getDownTime(),
4078 uint32_t(pointerCount), pointerProperties,
4079 samplePointerCoords,
4080 motionEvent->getXOffset(),
4081 motionEvent->getYOffset());
4082 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004083 }
4084 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004085 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004086
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004087 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004088 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004089 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004090 }
4091
4092 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004093 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004094 injectionState->injectionIsAsync = true;
4095 }
4096
4097 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004098 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004099
4100 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004101 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004102 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004103 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004104 }
4105
4106 mLock.unlock();
4107
4108 if (needWake) {
4109 mLooper->wake();
4110 }
4111
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004112 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004113 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004114 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004115
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004116 if (syncMode == InputEventInjectionSync::NONE) {
4117 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004118 } else {
4119 for (;;) {
4120 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004121 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004122 break;
4123 }
4124
4125 nsecs_t remainingTimeout = endTime - now();
4126 if (remainingTimeout <= 0) {
4127#if DEBUG_INJECTION
4128 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004129 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004130#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004131 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004132 break;
4133 }
4134
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004135 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004136 }
4137
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004138 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4139 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004140 while (injectionState->pendingForegroundDispatches != 0) {
4141#if DEBUG_INJECTION
4142 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004143 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004144#endif
4145 nsecs_t remainingTimeout = endTime - now();
4146 if (remainingTimeout <= 0) {
4147#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004148 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4149 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004150#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004151 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004152 break;
4153 }
4154
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004155 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004156 }
4157 }
4158 }
4159
4160 injectionState->release();
4161 } // release lock
4162
4163#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004164 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004165 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004166#endif
4167
4168 return injectionResult;
4169}
4170
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004171std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004172 std::array<uint8_t, 32> calculatedHmac;
4173 std::unique_ptr<VerifiedInputEvent> result;
4174 switch (event.getType()) {
4175 case AINPUT_EVENT_TYPE_KEY: {
4176 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4177 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4178 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004179 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004180 break;
4181 }
4182 case AINPUT_EVENT_TYPE_MOTION: {
4183 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4184 VerifiedMotionEvent verifiedMotionEvent =
4185 verifiedMotionEventFromMotionEvent(motionEvent);
4186 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004187 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004188 break;
4189 }
4190 default: {
4191 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4192 return nullptr;
4193 }
4194 }
4195 if (calculatedHmac == INVALID_HMAC) {
4196 return nullptr;
4197 }
4198 if (calculatedHmac != event.getHmac()) {
4199 return nullptr;
4200 }
4201 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004202}
4203
Michael Wrightd02c5b62014-02-10 15:10:22 -08004204bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004205 return injectorUid == 0 ||
4206 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004207}
4208
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004209void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004210 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004211 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004212 if (injectionState) {
4213#if DEBUG_INJECTION
4214 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004215 "injectorPid=%d, injectorUid=%d",
4216 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004217#endif
4218
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004219 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004220 // Log the outcome since the injector did not wait for the injection result.
4221 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004222 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004223 ALOGV("Asynchronous input event injection succeeded.");
4224 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004225 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004226 ALOGW("Asynchronous input event injection failed.");
4227 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004228 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004229 ALOGW("Asynchronous input event injection permission denied.");
4230 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004231 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004232 ALOGW("Asynchronous input event injection timed out.");
4233 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004234 case InputEventInjectionResult::PENDING:
4235 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4236 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004237 }
4238 }
4239
4240 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004241 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004242 }
4243}
4244
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004245void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4246 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004247 if (injectionState) {
4248 injectionState->pendingForegroundDispatches += 1;
4249 }
4250}
4251
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004252void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4253 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004254 if (injectionState) {
4255 injectionState->pendingForegroundDispatches -= 1;
4256
4257 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004258 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004259 }
4260 }
4261}
4262
Vishnu Nairad321cd2020-08-20 16:40:21 -07004263const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004264 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004265 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
4266 auto it = mWindowHandlesByDisplay.find(displayId);
4267 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004268}
4269
Michael Wrightd02c5b62014-02-10 15:10:22 -08004270sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004271 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004272 if (windowHandleToken == nullptr) {
4273 return nullptr;
4274 }
4275
Arthur Hungb92218b2018-08-14 12:00:21 +08004276 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004277 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004278 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004279 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004280 return windowHandle;
4281 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004282 }
4283 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004284 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004285}
4286
Vishnu Nairad321cd2020-08-20 16:40:21 -07004287sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4288 int displayId) const {
4289 if (windowHandleToken == nullptr) {
4290 return nullptr;
4291 }
4292
4293 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
4294 if (windowHandle->getToken() == windowHandleToken) {
4295 return windowHandle;
4296 }
4297 }
4298 return nullptr;
4299}
4300
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004301sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
4302 const sp<InputWindowHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004303 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004304 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00004305 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004306 if (handle->getId() == windowHandle->getId() &&
4307 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004308 if (windowHandle->getInfo()->displayId != it.first) {
4309 ALOGE("Found window %s in display %" PRId32
4310 ", but it should belong to display %" PRId32,
4311 windowHandle->getName().c_str(), it.first,
4312 windowHandle->getInfo()->displayId);
4313 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004314 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004315 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004316 }
4317 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004318 return nullptr;
4319}
4320
4321sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
4322 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4323 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004324}
4325
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004326bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
4327 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4328 const bool noInputChannel =
4329 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4330 if (connection != nullptr && noInputChannel) {
4331 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4332 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4333 return false;
4334 }
4335
4336 if (connection == nullptr) {
4337 if (!noInputChannel) {
4338 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4339 }
4340 return false;
4341 }
4342 if (!connection->responsive) {
4343 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4344 return false;
4345 }
4346 return true;
4347}
4348
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004349std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4350 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07004351 size_t count = mInputChannelsByToken.count(token);
4352 if (count == 0) {
4353 return nullptr;
4354 }
4355 return mInputChannelsByToken.at(token);
4356}
4357
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004358void InputDispatcher::updateWindowHandlesForDisplayLocked(
4359 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
4360 if (inputWindowHandles.empty()) {
4361 // Remove all handles on a display if there are no windows left.
4362 mWindowHandlesByDisplay.erase(displayId);
4363 return;
4364 }
4365
4366 // Since we compare the pointer of input window handles across window updates, we need
4367 // to make sure the handle object for the same window stays unchanged across updates.
4368 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07004369 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004370 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004371 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004372 }
4373
4374 std::vector<sp<InputWindowHandle>> newHandles;
4375 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
4376 if (!handle->updateInfo()) {
4377 // handle no longer valid
4378 continue;
4379 }
4380
4381 const InputWindowInfo* info = handle->getInfo();
4382 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4383 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4384 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01004385 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4386 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
4387 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004388 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004389 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004390 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004391 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004392 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004393 }
4394
4395 if (info->displayId != displayId) {
4396 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4397 handle->getName().c_str(), displayId, info->displayId);
4398 continue;
4399 }
4400
Robert Carredd13602020-04-13 17:24:34 -07004401 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4402 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004403 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004404 oldHandle->updateFrom(handle);
4405 newHandles.push_back(oldHandle);
4406 } else {
4407 newHandles.push_back(handle);
4408 }
4409 }
4410
4411 // Insert or replace
4412 mWindowHandlesByDisplay[displayId] = newHandles;
4413}
4414
Arthur Hung72d8dc32020-03-28 00:48:39 +00004415void InputDispatcher::setInputWindows(
4416 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4417 { // acquire lock
4418 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004419 for (const auto& [displayId, handles] : handlesPerDisplay) {
4420 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004421 }
4422 }
4423 // Wake up poll loop since it may need to make new input dispatching choices.
4424 mLooper->wake();
4425}
4426
Arthur Hungb92218b2018-08-14 12:00:21 +08004427/**
4428 * Called from InputManagerService, update window handle list by displayId that can receive input.
4429 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4430 * If set an empty list, remove all handles from the specific display.
4431 * For focused handle, check if need to change and send a cancel event to previous one.
4432 * For removed handle, check if need to send a cancel event if already in touch.
4433 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004434void InputDispatcher::setInputWindowsLocked(
4435 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004436 if (DEBUG_FOCUS) {
4437 std::string windowList;
4438 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4439 windowList += iwh->getName() + " ";
4440 }
4441 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4442 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004443
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004444 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4445 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4446 const bool noInputWindow =
4447 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4448 if (noInputWindow && window->getToken() != nullptr) {
4449 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4450 window->getName().c_str());
4451 window->releaseChannel();
4452 }
4453 }
4454
Arthur Hung72d8dc32020-03-28 00:48:39 +00004455 // Copy old handles for release if they are no longer present.
4456 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004457
Arthur Hung72d8dc32020-03-28 00:48:39 +00004458 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004459
Vishnu Nair958da932020-08-21 17:12:37 -07004460 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4461 if (mLastHoverWindowHandle &&
4462 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4463 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004464 mLastHoverWindowHandle = nullptr;
4465 }
4466
Vishnu Nairc519ff72021-01-21 08:23:08 -08004467 std::optional<FocusResolver::FocusChanges> changes =
4468 mFocusResolver.setInputWindows(displayId, windowHandles);
4469 if (changes) {
4470 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004471 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004472
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004473 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4474 mTouchStatesByDisplay.find(displayId);
4475 if (stateIt != mTouchStatesByDisplay.end()) {
4476 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004477 for (size_t i = 0; i < state.windows.size();) {
4478 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004479 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004480 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004481 ALOGD("Touched window was removed: %s in display %" PRId32,
4482 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004483 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004484 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004485 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4486 if (touchedInputChannel != nullptr) {
4487 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4488 "touched window was removed");
4489 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004490 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004491 state.windows.erase(state.windows.begin() + i);
4492 } else {
4493 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004494 }
4495 }
arthurhungb89ccb02020-12-30 16:19:01 +08004496
arthurhung6d4bed92021-03-17 11:59:33 +08004497 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004498 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004499 if (mDragState &&
4500 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004501 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004502 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004503 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004504 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004505
Arthur Hung72d8dc32020-03-28 00:48:39 +00004506 // Release information for windows that are no longer present.
4507 // This ensures that unused input channels are released promptly.
4508 // Otherwise, they might stick around until the window handle is destroyed
4509 // which might not happen until the next GC.
4510 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004511 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004512 if (DEBUG_FOCUS) {
4513 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004514 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004515 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004516 // To avoid making too many calls into the compat framework, only
4517 // check for window flags when windows are going away.
4518 // TODO(b/157929241) : delete this. This is only needed temporarily
4519 // in order to gather some data about the flag usage
4520 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4521 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4522 oldWindowHandle->getName().c_str());
4523 if (mCompatService != nullptr) {
4524 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4525 oldWindowHandle->getInfo()->ownerUid);
4526 }
4527 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004528 }
chaviw291d88a2019-02-14 10:33:58 -08004529 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004530}
4531
4532void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004533 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004534 if (DEBUG_FOCUS) {
4535 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4536 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4537 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004538 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004539 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004540
Chris Yea209fde2020-07-22 13:54:51 -07004541 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004542 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004543
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004544 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4545 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004546 }
4547
Chris Yea209fde2020-07-22 13:54:51 -07004548 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004549 if (inputApplicationHandle != nullptr) {
4550 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4551 } else {
4552 mFocusedApplicationHandlesByDisplay.erase(displayId);
4553 }
4554
4555 // No matter what the old focused application was, stop waiting on it because it is
4556 // no longer focused.
4557 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004558 } // release lock
4559
4560 // Wake up poll loop since it may need to make new input dispatching choices.
4561 mLooper->wake();
4562}
4563
Tiger Huang721e26f2018-07-24 22:26:19 +08004564/**
4565 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4566 * the display not specified.
4567 *
4568 * We track any unreleased events for each window. If a window loses the ability to receive the
4569 * released event, we will send a cancel event to it. So when the focused display is changed, we
4570 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4571 * display. The display-specified events won't be affected.
4572 */
4573void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004574 if (DEBUG_FOCUS) {
4575 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4576 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004577 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004578 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004579
4580 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004581 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004582 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004583 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004584 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004585 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004586 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004587 CancelationOptions
4588 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4589 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004590 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004591 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4592 }
4593 }
4594 mFocusedDisplayId = displayId;
4595
Chris Ye3c2d6f52020-08-09 10:39:48 -07004596 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004597 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004598 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004599
Vishnu Nairad321cd2020-08-20 16:40:21 -07004600 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004601 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004602 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004603 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004604 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004605 }
4606 }
4607 }
4608
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004609 if (DEBUG_FOCUS) {
4610 logDispatchStateLocked();
4611 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004612 } // release lock
4613
4614 // Wake up poll loop since it may need to make new input dispatching choices.
4615 mLooper->wake();
4616}
4617
Michael Wrightd02c5b62014-02-10 15:10:22 -08004618void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004619 if (DEBUG_FOCUS) {
4620 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4621 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004622
4623 bool changed;
4624 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004625 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004626
4627 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4628 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004629 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004630 }
4631
4632 if (mDispatchEnabled && !enabled) {
4633 resetAndDropEverythingLocked("dispatcher is being disabled");
4634 }
4635
4636 mDispatchEnabled = enabled;
4637 mDispatchFrozen = frozen;
4638 changed = true;
4639 } else {
4640 changed = false;
4641 }
4642
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004643 if (DEBUG_FOCUS) {
4644 logDispatchStateLocked();
4645 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004646 } // release lock
4647
4648 if (changed) {
4649 // Wake up poll loop since it may need to make new input dispatching choices.
4650 mLooper->wake();
4651 }
4652}
4653
4654void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004655 if (DEBUG_FOCUS) {
4656 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4657 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004658
4659 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004660 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004661
4662 if (mInputFilterEnabled == enabled) {
4663 return;
4664 }
4665
4666 mInputFilterEnabled = enabled;
4667 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4668 } // release lock
4669
4670 // Wake up poll loop since there might be work to do to drop everything.
4671 mLooper->wake();
4672}
4673
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004674void InputDispatcher::setInTouchMode(bool inTouchMode) {
4675 std::scoped_lock lock(mLock);
4676 mInTouchMode = inTouchMode;
4677}
4678
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004679void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4680 if (opacity < 0 || opacity > 1) {
4681 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4682 return;
4683 }
4684
4685 std::scoped_lock lock(mLock);
4686 mMaximumObscuringOpacityForTouch = opacity;
4687}
4688
4689void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4690 std::scoped_lock lock(mLock);
4691 mBlockUntrustedTouchesMode = mode;
4692}
4693
arthurhungb89ccb02020-12-30 16:19:01 +08004694bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4695 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004696 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004697 if (DEBUG_FOCUS) {
4698 ALOGD("Trivial transfer to same window.");
4699 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004700 return true;
4701 }
4702
Michael Wrightd02c5b62014-02-10 15:10:22 -08004703 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004704 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004705
chaviwfbe5d9c2018-12-26 12:23:37 -08004706 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4707 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004708 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004709 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004710 return false;
4711 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004712 if (DEBUG_FOCUS) {
4713 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4714 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4715 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004716 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004717 if (DEBUG_FOCUS) {
4718 ALOGD("Cannot transfer focus because windows are on different displays.");
4719 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004720 return false;
4721 }
4722
4723 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004724 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4725 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004726 for (size_t i = 0; i < state.windows.size(); i++) {
4727 const TouchedWindow& touchedWindow = state.windows[i];
4728 if (touchedWindow.windowHandle == fromWindowHandle) {
4729 int32_t oldTargetFlags = touchedWindow.targetFlags;
4730 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004731
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004732 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004733
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004734 int32_t newTargetFlags = oldTargetFlags &
4735 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4736 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004737 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004738
arthurhungb89ccb02020-12-30 16:19:01 +08004739 // Store the dragging window.
4740 if (isDragDrop) {
arthurhung6d4bed92021-03-17 11:59:33 +08004741 mDragState = std::make_unique<DragState>(toWindowHandle);
arthurhungb89ccb02020-12-30 16:19:01 +08004742 }
4743
Jeff Brownf086ddb2014-02-11 14:28:48 -08004744 found = true;
4745 goto Found;
4746 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004747 }
4748 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004749 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004750
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004751 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004752 if (DEBUG_FOCUS) {
4753 ALOGD("Focus transfer failed because from window did not have focus.");
4754 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004755 return false;
4756 }
4757
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004758 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4759 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004760 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004761 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004762 CancelationOptions
4763 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4764 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004765 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004766 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004767 }
4768
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004769 if (DEBUG_FOCUS) {
4770 logDispatchStateLocked();
4771 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004772 } // release lock
4773
4774 // Wake up poll loop since it may need to make new input dispatching choices.
4775 mLooper->wake();
4776 return true;
4777}
4778
4779void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004780 if (DEBUG_FOCUS) {
4781 ALOGD("Resetting and dropping all events (%s).", reason);
4782 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004783
4784 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4785 synthesizeCancelationEventsForAllConnectionsLocked(options);
4786
4787 resetKeyRepeatLocked();
4788 releasePendingEventLocked();
4789 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004790 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004791
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004792 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004793 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004794 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004795 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004796}
4797
4798void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004799 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004800 dumpDispatchStateLocked(dump);
4801
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004802 std::istringstream stream(dump);
4803 std::string line;
4804
4805 while (std::getline(stream, line, '\n')) {
4806 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004807 }
4808}
4809
Prabir Pradhan99987712020-11-10 18:43:05 -08004810std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4811 std::string dump;
4812
4813 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4814 toString(mFocusedWindowRequestedPointerCapture));
4815
4816 std::string windowName = "None";
4817 if (mWindowTokenWithPointerCapture) {
4818 const sp<InputWindowHandle> captureWindowHandle =
4819 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4820 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4821 : "token has capture without window";
4822 }
4823 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4824
4825 return dump;
4826}
4827
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004828void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004829 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4830 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4831 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004832 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004833
Tiger Huang721e26f2018-07-24 22:26:19 +08004834 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4835 dump += StringPrintf(INDENT "FocusedApplications:\n");
4836 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4837 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004838 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004839 const std::chrono::duration timeout =
4840 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004841 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004842 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004843 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004844 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004845 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004846 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004847 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004848
Vishnu Nairc519ff72021-01-21 08:23:08 -08004849 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08004850 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004851
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004852 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004853 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004854 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4855 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004856 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004857 state.displayId, toString(state.down), toString(state.split),
4858 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004859 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004860 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004861 for (size_t i = 0; i < state.windows.size(); i++) {
4862 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004863 dump += StringPrintf(INDENT4
4864 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4865 i, touchedWindow.windowHandle->getName().c_str(),
4866 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004867 }
4868 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004869 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004870 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004871 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004872 dump += INDENT3 "Portal windows:\n";
4873 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004874 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004875 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4876 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004877 }
4878 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004879 }
4880 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004881 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004882 }
4883
arthurhung6d4bed92021-03-17 11:59:33 +08004884 if (mDragState) {
4885 dump += StringPrintf(INDENT "DragState:\n");
4886 mDragState->dump(dump, INDENT2);
4887 }
4888
Arthur Hungb92218b2018-08-14 12:00:21 +08004889 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004890 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004891 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004892 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004893 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004894 dump += INDENT2 "Windows:\n";
4895 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004896 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004897 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004898
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004899 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004900 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004901 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004902 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004903 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00004904 "applicationInfo.name=%s, "
4905 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004906 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004907 i, windowInfo->name.c_str(), windowInfo->id,
4908 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004909 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004910 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004911 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004912 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004913 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004914 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004915 windowInfo->frameLeft, windowInfo->frameTop,
4916 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004917 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00004918 windowInfo->applicationInfo.name.c_str(),
4919 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004920 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004921 dump += StringPrintf(", inputFeatures=%s",
4922 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004923 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004924 "ms, trustedOverlay=%s, hasToken=%s, "
4925 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004926 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004927 millis(windowInfo->dispatchingTimeout),
4928 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004929 toString(windowInfo->token != nullptr),
4930 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004931 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004932 }
4933 } else {
4934 dump += INDENT2 "Windows: <none>\n";
4935 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004936 }
4937 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004938 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004939 }
4940
Michael Wright3dd60e22019-03-27 22:06:44 +00004941 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004942 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004943 const std::vector<Monitor>& monitors = it.second;
4944 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4945 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004946 }
4947 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004948 const std::vector<Monitor>& monitors = it.second;
4949 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4950 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004951 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004952 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004953 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004954 }
4955
4956 nsecs_t currentTime = now();
4957
4958 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004959 if (!mRecentQueue.empty()) {
4960 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004961 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004962 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004963 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004964 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004965 }
4966 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004967 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004968 }
4969
4970 // Dump event currently being dispatched.
4971 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004972 dump += INDENT "PendingEvent:\n";
4973 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004974 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004975 dump += StringPrintf(", age=%" PRId64 "ms\n",
4976 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004977 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004978 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004979 }
4980
4981 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004982 if (!mInboundQueue.empty()) {
4983 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004984 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004985 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004986 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004987 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004988 }
4989 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004990 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004991 }
4992
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004993 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004994 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004995 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4996 const KeyReplacement& replacement = pair.first;
4997 int32_t newKeyCode = pair.second;
4998 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004999 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005000 }
5001 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005002 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005003 }
5004
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005005 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005006 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005007 for (const auto& pair : mConnectionsByFd) {
5008 const sp<Connection>& connection = pair.second;
5009 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005010 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005011 pair.first, connection->getInputChannelName().c_str(),
5012 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005013 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005014
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005015 if (!connection->outboundQueue.empty()) {
5016 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5017 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005018 dump += dumpQueue(connection->outboundQueue, currentTime);
5019
Michael Wrightd02c5b62014-02-10 15:10:22 -08005020 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005021 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005022 }
5023
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005024 if (!connection->waitQueue.empty()) {
5025 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5026 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005027 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005028 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005029 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005030 }
5031 }
5032 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005033 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005034 }
5035
5036 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005037 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5038 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005039 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005040 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005041 }
5042
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005043 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005044 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5045 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5046 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005047}
5048
Michael Wright3dd60e22019-03-27 22:06:44 +00005049void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5050 const size_t numMonitors = monitors.size();
5051 for (size_t i = 0; i < numMonitors; i++) {
5052 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005053 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005054 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5055 dump += "\n";
5056 }
5057}
5058
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005059Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Garfield Tan15601662020-09-22 15:32:38 -07005060#if DEBUG_CHANNEL_CREATION
5061 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005062#endif
5063
Garfield Tan15601662020-09-22 15:32:38 -07005064 std::shared_ptr<InputChannel> serverChannel;
5065 std::unique_ptr<InputChannel> clientChannel;
5066 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5067
5068 if (result) {
5069 return base::Error(result) << "Failed to open input channel pair with name " << name;
5070 }
5071
Michael Wrightd02c5b62014-02-10 15:10:22 -08005072 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005073 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07005074 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005075
Garfield Tan15601662020-09-22 15:32:38 -07005076 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005077 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07005078 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005079
Michael Wrightd02c5b62014-02-10 15:10:22 -08005080 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
5081 } // release lock
5082
5083 // Wake the looper because some connections have changed.
5084 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005085 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005086}
5087
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005088Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5089 bool isGestureMonitor,
5090 const std::string& name,
5091 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005092 std::shared_ptr<InputChannel> serverChannel;
5093 std::unique_ptr<InputChannel> clientChannel;
5094 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5095 if (result) {
5096 return base::Error(result) << "Failed to open input channel pair with name " << name;
5097 }
5098
Michael Wright3dd60e22019-03-27 22:06:44 +00005099 { // acquire lock
5100 std::scoped_lock _l(mLock);
5101
5102 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005103 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5104 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005105 }
5106
Garfield Tan15601662020-09-22 15:32:38 -07005107 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00005108
Garfield Tan15601662020-09-22 15:32:38 -07005109 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005110 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07005111 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005112
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005113 auto& monitorsByDisplay =
5114 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005115 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005116
5117 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005118 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5119 displayId, toString(isGestureMonitor), pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005120 }
Garfield Tan15601662020-09-22 15:32:38 -07005121
Michael Wright3dd60e22019-03-27 22:06:44 +00005122 // Wake the looper because some connections have changed.
5123 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005124 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005125}
5126
Garfield Tan15601662020-09-22 15:32:38 -07005127status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005128 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005129 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005130
Garfield Tan15601662020-09-22 15:32:38 -07005131 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005132 if (status) {
5133 return status;
5134 }
5135 } // release lock
5136
5137 // Wake the poll loop because removing the connection may have changed the current
5138 // synchronization state.
5139 mLooper->wake();
5140 return OK;
5141}
5142
Garfield Tan15601662020-09-22 15:32:38 -07005143status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5144 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005145 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005146 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005147 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005148 return BAD_VALUE;
5149 }
5150
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005151 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005152 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07005153
Michael Wrightd02c5b62014-02-10 15:10:22 -08005154 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005155 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005156 }
5157
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005158 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005159
5160 nsecs_t currentTime = now();
5161 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5162
5163 connection->status = Connection::STATUS_ZOMBIE;
5164 return OK;
5165}
5166
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005167void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5168 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5169 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005170}
5171
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005172void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005173 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005174 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005175 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005176 std::vector<Monitor>& monitors = it->second;
5177 const size_t numMonitors = monitors.size();
5178 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005179 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005180 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5181 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005182 monitors.erase(monitors.begin() + i);
5183 break;
5184 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005185 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005186 if (monitors.empty()) {
5187 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005188 } else {
5189 ++it;
5190 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005191 }
5192}
5193
Michael Wright3dd60e22019-03-27 22:06:44 +00005194status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5195 { // acquire lock
5196 std::scoped_lock _l(mLock);
5197 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5198
5199 if (!foundDisplayId) {
5200 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5201 return BAD_VALUE;
5202 }
5203 int32_t displayId = foundDisplayId.value();
5204
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005205 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5206 mTouchStatesByDisplay.find(displayId);
5207 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005208 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5209 return BAD_VALUE;
5210 }
5211
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005212 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005213 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005214 std::optional<int32_t> foundDeviceId;
5215 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005216 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005217 requestingChannel = touchedMonitor.monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005218 foundDeviceId = state.deviceId;
5219 }
5220 }
5221 if (!foundDeviceId || !state.down) {
5222 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005223 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005224 return BAD_VALUE;
5225 }
5226 int32_t deviceId = foundDeviceId.value();
5227
5228 // Send cancel events to all the input channels we're stealing from.
5229 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005230 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005231 options.deviceId = deviceId;
5232 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005233 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005234 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005235 std::shared_ptr<InputChannel> channel =
5236 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005237 if (channel != nullptr) {
5238 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005239 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005240 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005241 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005242 canceledWindows += "]";
5243 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5244 canceledWindows.c_str());
5245
Michael Wright3dd60e22019-03-27 22:06:44 +00005246 // Then clear the current touch state so we stop dispatching to them as well.
5247 state.filterNonMonitors();
5248 }
5249 return OK;
5250}
5251
Prabir Pradhan99987712020-11-10 18:43:05 -08005252void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5253 { // acquire lock
5254 std::scoped_lock _l(mLock);
5255 if (DEBUG_FOCUS) {
5256 const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
5257 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5258 windowHandle != nullptr ? windowHandle->getName().c_str()
5259 : "token without window");
5260 }
5261
Vishnu Nairc519ff72021-01-21 08:23:08 -08005262 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005263 if (focusedToken != windowToken) {
5264 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5265 enabled ? "enable" : "disable");
5266 return;
5267 }
5268
5269 if (enabled == mFocusedWindowRequestedPointerCapture) {
5270 ALOGW("Ignoring request to %s Pointer Capture: "
5271 "window has %s requested pointer capture.",
5272 enabled ? "enable" : "disable", enabled ? "already" : "not");
5273 return;
5274 }
5275
5276 mFocusedWindowRequestedPointerCapture = enabled;
5277 setPointerCaptureLocked(enabled);
5278 } // release lock
5279
5280 // Wake the thread to process command entries.
5281 mLooper->wake();
5282}
5283
Michael Wright3dd60e22019-03-27 22:06:44 +00005284std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5285 const sp<IBinder>& token) {
5286 for (const auto& it : mGestureMonitorsByDisplay) {
5287 const std::vector<Monitor>& monitors = it.second;
5288 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005289 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005290 return it.first;
5291 }
5292 }
5293 }
5294 return std::nullopt;
5295}
5296
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005297std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5298 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5299 if (gesturePid.has_value()) {
5300 return gesturePid;
5301 }
5302 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5303}
5304
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005305sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005306 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005307 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005308 }
5309
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005310 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005311 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005312 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005313 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005314 }
5315 }
Robert Carr4e670e52018-08-15 13:26:12 -07005316
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005317 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005318}
5319
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005320std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5321 sp<Connection> connection = getConnectionLocked(connectionToken);
5322 if (connection == nullptr) {
5323 return "<nullptr>";
5324 }
5325 return connection->getInputChannelName();
5326}
5327
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005328void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005329 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005330 removeByValue(mConnectionsByFd, connection);
5331}
5332
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005333void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5334 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10005335 bool handled, nsecs_t consumeTime) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005336 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5337 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005338 commandEntry->connection = connection;
5339 commandEntry->eventTime = currentTime;
5340 commandEntry->seq = seq;
5341 commandEntry->handled = handled;
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10005342 commandEntry->consumeTime = consumeTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005343 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005344}
5345
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005346void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5347 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005348 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005349 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005350
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005351 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5352 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005353 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005354 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005355}
5356
Vishnu Nairad321cd2020-08-20 16:40:21 -07005357void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5358 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005359 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5360 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005361 commandEntry->oldToken = oldToken;
5362 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005363 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005364}
5365
arthurhungf452d0b2021-01-06 00:19:52 +08005366void InputDispatcher::notifyDropWindowLocked(const sp<IBinder>& token, float x, float y) {
5367 std::unique_ptr<CommandEntry> commandEntry =
5368 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyDropWindowLockedInterruptible);
5369 commandEntry->newToken = token;
5370 commandEntry->x = x;
5371 commandEntry->y = y;
5372 postCommandLocked(std::move(commandEntry));
5373}
5374
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005375void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5376 if (connection == nullptr) {
5377 LOG_ALWAYS_FATAL("Caller must check for nullness");
5378 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005379 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5380 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005381 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005382 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005383 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005384 return;
5385 }
5386 /**
5387 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5388 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5389 * has changed. This could cause newer entries to time out before the already dispatched
5390 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5391 * processes the events linearly. So providing information about the oldest entry seems to be
5392 * most useful.
5393 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005394 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005395 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5396 std::string reason =
5397 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005398 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005399 ns2ms(currentWait),
5400 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005401 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005402 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005403
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005404 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5405
5406 // Stop waking up for events on this connection, it is already unresponsive
5407 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005408}
5409
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005410void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5411 std::string reason =
5412 StringPrintf("%s does not have a focused window", application->getName().c_str());
5413 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005414
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005415 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5416 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5417 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005418 postCommandLocked(std::move(commandEntry));
5419}
5420
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005421void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5422 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5423 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5424 commandEntry->obscuringPackage = obscuringPackage;
5425 postCommandLocked(std::move(commandEntry));
5426}
5427
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005428void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
5429 const std::string& reason) {
5430 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5431 updateLastAnrStateLocked(windowLabel, reason);
5432}
5433
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005434void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5435 const std::string& reason) {
5436 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005437 updateLastAnrStateLocked(windowLabel, reason);
5438}
5439
5440void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5441 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005442 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005443 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005444 struct tm tm;
5445 localtime_r(&t, &tm);
5446 char timestr[64];
5447 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005448 mLastAnrState.clear();
5449 mLastAnrState += INDENT "ANR:\n";
5450 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005451 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5452 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005453 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005454}
5455
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005456void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005457 mLock.unlock();
5458
5459 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5460
5461 mLock.lock();
5462}
5463
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005464void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005465 sp<Connection> connection = commandEntry->connection;
5466
5467 if (connection->status != Connection::STATUS_ZOMBIE) {
5468 mLock.unlock();
5469
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005470 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005471
5472 mLock.lock();
5473 }
5474}
5475
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005476void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005477 sp<IBinder> oldToken = commandEntry->oldToken;
5478 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005479 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005480 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005481 mLock.lock();
5482}
5483
arthurhungf452d0b2021-01-06 00:19:52 +08005484void InputDispatcher::doNotifyDropWindowLockedInterruptible(CommandEntry* commandEntry) {
5485 sp<IBinder> newToken = commandEntry->newToken;
5486 mLock.unlock();
5487 mPolicy->notifyDropWindow(newToken, commandEntry->x, commandEntry->y);
5488 mLock.lock();
5489}
5490
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005491void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005492 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005493
5494 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5495
5496 mLock.lock();
5497}
5498
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005499void InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005500 mLock.unlock();
5501
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005502 mPolicy->notifyWindowUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005503
5504 mLock.lock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005505}
5506
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005507void InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005508 mLock.unlock();
5509
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005510 mPolicy->notifyMonitorUnresponsive(commandEntry->pid, commandEntry->reason);
5511
5512 mLock.lock();
5513}
5514
5515void InputDispatcher::doNotifyWindowResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5516 mLock.unlock();
5517
5518 mPolicy->notifyWindowResponsive(commandEntry->connectionToken);
5519
5520 mLock.lock();
5521}
5522
5523void InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5524 mLock.unlock();
5525
5526 mPolicy->notifyMonitorResponsive(commandEntry->pid);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005527
5528 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005529}
5530
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005531void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5532 mLock.unlock();
5533
5534 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5535
5536 mLock.lock();
5537}
5538
Michael Wrightd02c5b62014-02-10 15:10:22 -08005539void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5540 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005541 KeyEntry& entry = *(commandEntry->keyEntry);
5542 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005543
5544 mLock.unlock();
5545
Michael Wright2b3c3302018-03-02 17:19:13 +00005546 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005547 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005548 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005549 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5550 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005551 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005552 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005553
5554 mLock.lock();
5555
5556 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005557 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005558 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005559 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005560 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005561 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5562 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005563 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005564}
5565
chaviwfd6d3512019-03-25 13:23:49 -07005566void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5567 mLock.unlock();
5568 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5569 mLock.lock();
5570}
5571
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005572/**
5573 * Connection is responsive if it has no events in the waitQueue that are older than the
5574 * current time.
5575 */
5576static bool isConnectionResponsive(const Connection& connection) {
5577 const nsecs_t currentTime = now();
5578 for (const DispatchEntry* entry : connection.waitQueue) {
5579 if (entry->timeoutTime < currentTime) {
5580 return false;
5581 }
5582 }
5583 return true;
5584}
5585
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005586void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005587 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005588 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005589 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005590 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005591
5592 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005593 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005594 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005595 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005596 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005597 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005598 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005599 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005600 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5601 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005602 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005603 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005604
5605 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005606 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005607 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005608 restartEvent =
5609 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005610 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005611 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005612 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5613 handled);
5614 } else {
5615 restartEvent = false;
5616 }
5617
5618 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005619 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005620 // contents of the wait queue to have been drained, so we need to double-check
5621 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005622 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5623 if (dispatchEntryIt != connection->waitQueue.end()) {
5624 dispatchEntry = *dispatchEntryIt;
5625 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005626 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5627 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005628 if (!connection->responsive) {
5629 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005630 if (connection->responsive) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005631 // The connection was unresponsive, and now it's responsive.
5632 processConnectionResponsiveLocked(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005633 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005634 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005635 traceWaitQueueLength(connection);
5636 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005637 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005638 traceOutboundQueueLength(connection);
5639 } else {
5640 releaseDispatchEntry(dispatchEntry);
5641 }
5642 }
5643
5644 // Start the next dispatch cycle for this connection.
5645 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005646}
5647
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005648void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
5649 std::unique_ptr<CommandEntry> monitorUnresponsiveCommand = std::make_unique<CommandEntry>(
5650 &InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible);
5651 monitorUnresponsiveCommand->pid = pid;
5652 monitorUnresponsiveCommand->reason = std::move(reason);
5653 postCommandLocked(std::move(monitorUnresponsiveCommand));
5654}
5655
5656void InputDispatcher::sendWindowUnresponsiveCommandLocked(sp<IBinder> connectionToken,
5657 std::string reason) {
5658 std::unique_ptr<CommandEntry> windowUnresponsiveCommand = std::make_unique<CommandEntry>(
5659 &InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible);
5660 windowUnresponsiveCommand->connectionToken = std::move(connectionToken);
5661 windowUnresponsiveCommand->reason = std::move(reason);
5662 postCommandLocked(std::move(windowUnresponsiveCommand));
5663}
5664
5665void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
5666 std::unique_ptr<CommandEntry> monitorResponsiveCommand = std::make_unique<CommandEntry>(
5667 &InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible);
5668 monitorResponsiveCommand->pid = pid;
5669 postCommandLocked(std::move(monitorResponsiveCommand));
5670}
5671
5672void InputDispatcher::sendWindowResponsiveCommandLocked(sp<IBinder> connectionToken) {
5673 std::unique_ptr<CommandEntry> windowResponsiveCommand = std::make_unique<CommandEntry>(
5674 &InputDispatcher::doNotifyWindowResponsiveLockedInterruptible);
5675 windowResponsiveCommand->connectionToken = std::move(connectionToken);
5676 postCommandLocked(std::move(windowResponsiveCommand));
5677}
5678
5679/**
5680 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5681 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5682 * command entry to the command queue.
5683 */
5684void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5685 std::string reason) {
5686 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5687 if (connection.monitor) {
5688 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5689 reason.c_str());
5690 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5691 if (!pid.has_value()) {
5692 ALOGE("Could not find unresponsive monitor for connection %s",
5693 connection.inputChannel->getName().c_str());
5694 return;
5695 }
5696 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5697 return;
5698 }
5699 // If not a monitor, must be a window
5700 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5701 reason.c_str());
5702 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5703}
5704
5705/**
5706 * Tell the policy that a connection has become responsive so that it can stop ANR.
5707 */
5708void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5709 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5710 if (connection.monitor) {
5711 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5712 if (!pid.has_value()) {
5713 ALOGE("Could not find responsive monitor for connection %s",
5714 connection.inputChannel->getName().c_str());
5715 return;
5716 }
5717 sendMonitorResponsiveCommandLocked(pid.value());
5718 return;
5719 }
5720 // If not a monitor, must be a window
5721 sendWindowResponsiveCommandLocked(connectionToken);
5722}
5723
Michael Wrightd02c5b62014-02-10 15:10:22 -08005724bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005725 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005726 KeyEntry& keyEntry, bool handled) {
5727 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005728 if (!handled) {
5729 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005730 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005731 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005732 return false;
5733 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005734
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005735 // Get the fallback key state.
5736 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005737 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005738 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005739 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005740 connection->inputState.removeFallbackKey(originalKeyCode);
5741 }
5742
5743 if (handled || !dispatchEntry->hasForegroundTarget()) {
5744 // If the application handles the original key for which we previously
5745 // generated a fallback or if the window is not a foreground window,
5746 // then cancel the associated fallback key, if any.
5747 if (fallbackKeyCode != -1) {
5748 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005749#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005750 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005751 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005752 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005753#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005754 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005755 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005756
5757 mLock.unlock();
5758
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005759 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005760 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005761
5762 mLock.lock();
5763
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005764 // Cancel the fallback key.
5765 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005766 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005767 "application handled the original non-fallback key "
5768 "or is no longer a foreground target, "
5769 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005770 options.keyCode = fallbackKeyCode;
5771 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005772 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005773 connection->inputState.removeFallbackKey(originalKeyCode);
5774 }
5775 } else {
5776 // If the application did not handle a non-fallback key, first check
5777 // that we are in a good state to perform unhandled key event processing
5778 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005779 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005780 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005781#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005782 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005783 "since this is not an initial down. "
5784 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005785 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005786#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005787 return false;
5788 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005789
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005790 // Dispatch the unhandled key to the policy.
5791#if DEBUG_OUTBOUND_EVENT_DETAILS
5792 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005793 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005794 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005795#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005796 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005797
5798 mLock.unlock();
5799
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005800 bool fallback =
5801 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005802 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005803
5804 mLock.lock();
5805
5806 if (connection->status != Connection::STATUS_NORMAL) {
5807 connection->inputState.removeFallbackKey(originalKeyCode);
5808 return false;
5809 }
5810
5811 // Latch the fallback keycode for this key on an initial down.
5812 // The fallback keycode cannot change at any other point in the lifecycle.
5813 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005814 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005815 fallbackKeyCode = event.getKeyCode();
5816 } else {
5817 fallbackKeyCode = AKEYCODE_UNKNOWN;
5818 }
5819 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5820 }
5821
5822 ALOG_ASSERT(fallbackKeyCode != -1);
5823
5824 // Cancel the fallback key if the policy decides not to send it anymore.
5825 // We will continue to dispatch the key to the policy but we will no
5826 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005827 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5828 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005829#if DEBUG_OUTBOUND_EVENT_DETAILS
5830 if (fallback) {
5831 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005832 "as a fallback for %d, but on the DOWN it had requested "
5833 "to send %d instead. Fallback canceled.",
5834 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005835 } else {
5836 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005837 "but on the DOWN it had requested to send %d. "
5838 "Fallback canceled.",
5839 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005840 }
5841#endif
5842
5843 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5844 "canceling fallback, policy no longer desires it");
5845 options.keyCode = fallbackKeyCode;
5846 synthesizeCancelationEventsForConnectionLocked(connection, options);
5847
5848 fallback = false;
5849 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005850 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005851 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005852 }
5853 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005854
5855#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005856 {
5857 std::string msg;
5858 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5859 connection->inputState.getFallbackKeys();
5860 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005861 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005862 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005863 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005864 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005865 }
5866#endif
5867
5868 if (fallback) {
5869 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005870 keyEntry.eventTime = event.getEventTime();
5871 keyEntry.deviceId = event.getDeviceId();
5872 keyEntry.source = event.getSource();
5873 keyEntry.displayId = event.getDisplayId();
5874 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5875 keyEntry.keyCode = fallbackKeyCode;
5876 keyEntry.scanCode = event.getScanCode();
5877 keyEntry.metaState = event.getMetaState();
5878 keyEntry.repeatCount = event.getRepeatCount();
5879 keyEntry.downTime = event.getDownTime();
5880 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005881
5882#if DEBUG_OUTBOUND_EVENT_DETAILS
5883 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005884 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005885 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005886#endif
5887 return true; // restart the event
5888 } else {
5889#if DEBUG_OUTBOUND_EVENT_DETAILS
5890 ALOGD("Unhandled key event: No fallback key.");
5891#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005892
5893 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005894 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005895 }
5896 }
5897 return false;
5898}
5899
5900bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005901 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005902 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005903 return false;
5904}
5905
5906void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5907 mLock.unlock();
5908
Sean Stoutb4e0a592021-02-23 07:34:53 -08005909 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType,
5910 commandEntry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005911
5912 mLock.lock();
5913}
5914
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005915void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5916 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005917 // TODO Write some statistics about how long we spend waiting.
5918}
5919
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005920/**
5921 * Report the touch event latency to the statsd server.
5922 * Input events are reported for statistics if:
5923 * - This is a touchscreen event
5924 * - InputFilter is not enabled
5925 * - Event is not injected or synthesized
5926 *
5927 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5928 * from getting aggregated with the "old" data.
5929 */
5930void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5931 REQUIRES(mLock) {
5932 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5933 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5934 if (!reportForStatistics) {
5935 return;
5936 }
5937
5938 if (mTouchStatistics.shouldReport()) {
5939 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5940 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5941 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5942 mTouchStatistics.reset();
5943 }
5944 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5945 mTouchStatistics.addValue(latencyMicros);
5946}
5947
Michael Wrightd02c5b62014-02-10 15:10:22 -08005948void InputDispatcher::traceInboundQueueLengthLocked() {
5949 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005950 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005951 }
5952}
5953
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005954void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005955 if (ATRACE_ENABLED()) {
5956 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005957 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005958 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005959 }
5960}
5961
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005962void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005963 if (ATRACE_ENABLED()) {
5964 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005965 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005966 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005967 }
5968}
5969
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005970void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005971 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005972
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005973 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005974 dumpDispatchStateLocked(dump);
5975
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005976 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005977 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005978 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005979 }
5980}
5981
5982void InputDispatcher::monitor() {
5983 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005984 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005985 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005986 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005987}
5988
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005989/**
5990 * Wake up the dispatcher and wait until it processes all events and commands.
5991 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5992 * this method can be safely called from any thread, as long as you've ensured that
5993 * the work you are interested in completing has already been queued.
5994 */
5995bool InputDispatcher::waitForIdle() {
5996 /**
5997 * Timeout should represent the longest possible time that a device might spend processing
5998 * events and commands.
5999 */
6000 constexpr std::chrono::duration TIMEOUT = 100ms;
6001 std::unique_lock lock(mLock);
6002 mLooper->wake();
6003 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6004 return result == std::cv_status::no_timeout;
6005}
6006
Vishnu Naire798b472020-07-23 13:52:21 -07006007/**
6008 * Sets focus to the window identified by the token. This must be called
6009 * after updating any input window handles.
6010 *
6011 * Params:
6012 * request.token - input channel token used to identify the window that should gain focus.
6013 * request.focusedToken - the token that the caller expects currently to be focused. If the
6014 * specified token does not match the currently focused window, this request will be dropped.
6015 * If the specified focused token matches the currently focused window, the call will succeed.
6016 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6017 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6018 * when requesting the focus change. This determines which request gets
6019 * precedence if there is a focus change request from another source such as pointer down.
6020 */
Vishnu Nair958da932020-08-21 17:12:37 -07006021void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6022 { // acquire lock
6023 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006024 std::optional<FocusResolver::FocusChanges> changes =
6025 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6026 if (changes) {
6027 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006028 }
6029 } // release lock
6030 // Wake up poll loop since it may need to make new input dispatching choices.
6031 mLooper->wake();
6032}
6033
Vishnu Nairc519ff72021-01-21 08:23:08 -08006034void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6035 if (changes.oldFocus) {
6036 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006037 if (focusedInputChannel) {
6038 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6039 "focus left window");
6040 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006041 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006042 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006043 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006044 if (changes.newFocus) {
6045 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006046 }
6047
Prabir Pradhan99987712020-11-10 18:43:05 -08006048 // If a window has pointer capture, then it must have focus. We need to ensure that this
6049 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6050 // If the window loses focus before it loses pointer capture, then the window can be in a state
6051 // where it has pointer capture but not focus, violating the contract. Therefore we must
6052 // dispatch the pointer capture event before the focus event. Since focus events are added to
6053 // the front of the queue (above), we add the pointer capture event to the front of the queue
6054 // after the focus events are added. This ensures the pointer capture event ends up at the
6055 // front.
6056 disablePointerCaptureForcedLocked();
6057
Vishnu Nairc519ff72021-01-21 08:23:08 -08006058 if (mFocusedDisplayId == changes.displayId) {
6059 notifyFocusChangedLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006060 }
6061}
Vishnu Nair958da932020-08-21 17:12:37 -07006062
Prabir Pradhan99987712020-11-10 18:43:05 -08006063void InputDispatcher::disablePointerCaptureForcedLocked() {
6064 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
6065 return;
6066 }
6067
6068 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6069
6070 if (mFocusedWindowRequestedPointerCapture) {
6071 mFocusedWindowRequestedPointerCapture = false;
6072 setPointerCaptureLocked(false);
6073 }
6074
6075 if (!mWindowTokenWithPointerCapture) {
6076 // No need to send capture changes because no window has capture.
6077 return;
6078 }
6079
6080 if (mPendingEvent != nullptr) {
6081 // Move the pending event to the front of the queue. This will give the chance
6082 // for the pending event to be dropped if it is a captured event.
6083 mInboundQueue.push_front(mPendingEvent);
6084 mPendingEvent = nullptr;
6085 }
6086
6087 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
6088 false /* hasCapture */);
6089 mInboundQueue.push_front(std::move(entry));
6090}
6091
Prabir Pradhan99987712020-11-10 18:43:05 -08006092void InputDispatcher::setPointerCaptureLocked(bool enabled) {
6093 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
6094 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
6095 commandEntry->enabled = enabled;
6096 postCommandLocked(std::move(commandEntry));
6097}
6098
6099void InputDispatcher::doSetPointerCaptureLockedInterruptible(
6100 android::inputdispatcher::CommandEntry* commandEntry) {
6101 mLock.unlock();
6102
6103 mPolicy->setPointerCapture(commandEntry->enabled);
6104
6105 mLock.lock();
6106}
6107
Garfield Tane84e6f92019-08-29 17:28:41 -07006108} // namespace android::inputdispatcher