blob: 63dd1ac838d873415ff8eee508ad45e574cae1b4 [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
40// Log debug messages about the app switch latency optimization.
41#define DEBUG_APP_SWITCH 0
42
43// Log debug messages about hover events.
44#define DEBUG_HOVER 0
45
46#include "InputDispatcher.h"
47
Michael Wright2b3c3302018-03-02 17:19:13 +000048#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080049#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050050#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070051#include <binder/Binder.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080052#include <input/InputDevice.h>
Michael Wright44753b12020-07-08 13:48:11 +010053#include <input/InputWindow.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070054#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000055#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070056#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010057#include <statslog.h>
58#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070059#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080060
Michael Wright44753b12020-07-08 13:48:11 +010061#include <cerrno>
62#include <cinttypes>
63#include <climits>
64#include <cstddef>
65#include <ctime>
66#include <queue>
67#include <sstream>
68
69#include "Connection.h"
70
Michael Wrightd02c5b62014-02-10 15:10:22 -080071#define INDENT " "
72#define INDENT2 " "
73#define INDENT3 " "
74#define INDENT4 " "
75
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080076using android::base::StringPrintf;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080077using android::os::BlockUntrustedTouchesMode;
78using android::os::InputEventInjectionResult;
79using android::os::InputEventInjectionSync;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080080
Garfield Tane84e6f92019-08-29 17:28:41 -070081namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080082
83// Default input dispatching timeout if there is no focused application or paused window
84// from which to determine an appropriate dispatching timeout.
Siarhei Vishniakou70622952020-07-30 11:17:23 -050085constexpr std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT =
86 std::chrono::milliseconds(android::os::IInputConstants::DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
Michael Wrightd02c5b62014-02-10 15:10:22 -080087
88// Amount of time to allow for all pending events to be processed when an app switch
89// key is on the way. This is used to preempt input dispatch and drop input events
90// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000091constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080092
93// Amount of time to allow for an event to be dispatched (measured since its eventTime)
94// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000095constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080096
Michael Wrightd02c5b62014-02-10 15:10:22 -080097// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +000098constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
99
100// Log a warning when an interception call takes longer than this to process.
101constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800102
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700103// Additional key latency in case a connection is still processing some motion events.
104// This will help with the case when a user touched a button that opens a new window,
105// and gives us the chance to dispatch the key to this new window.
106constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
107
Michael Wrightd02c5b62014-02-10 15:10:22 -0800108// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000109constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
110
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000111// Event log tags. See EventLogTags.logtags for reference
112constexpr int LOGTAG_INPUT_INTERACTION = 62000;
113constexpr int LOGTAG_INPUT_FOCUS = 62001;
114
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115static inline nsecs_t now() {
116 return systemTime(SYSTEM_TIME_MONOTONIC);
117}
118
119static inline const char* toString(bool value) {
120 return value ? "true" : "false";
121}
122
123static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700124 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
125 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800126}
127
128static bool isValidKeyAction(int32_t action) {
129 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700130 case AKEY_EVENT_ACTION_DOWN:
131 case AKEY_EVENT_ACTION_UP:
132 return true;
133 default:
134 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800135 }
136}
137
138static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700139 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800140 ALOGE("Key event has invalid action code 0x%x", action);
141 return false;
142 }
143 return true;
144}
145
Michael Wright7b159c92015-05-14 14:48:03 +0100146static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800147 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700148 case AMOTION_EVENT_ACTION_DOWN:
149 case AMOTION_EVENT_ACTION_UP:
150 case AMOTION_EVENT_ACTION_CANCEL:
151 case AMOTION_EVENT_ACTION_MOVE:
152 case AMOTION_EVENT_ACTION_OUTSIDE:
153 case AMOTION_EVENT_ACTION_HOVER_ENTER:
154 case AMOTION_EVENT_ACTION_HOVER_MOVE:
155 case AMOTION_EVENT_ACTION_HOVER_EXIT:
156 case AMOTION_EVENT_ACTION_SCROLL:
157 return true;
158 case AMOTION_EVENT_ACTION_POINTER_DOWN:
159 case AMOTION_EVENT_ACTION_POINTER_UP: {
160 int32_t index = getMotionEventActionPointerIndex(action);
161 return index >= 0 && index < pointerCount;
162 }
163 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
164 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
165 return actionButton != 0;
166 default:
167 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800168 }
169}
170
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500171static int64_t millis(std::chrono::nanoseconds t) {
172 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
173}
174
Michael Wright7b159c92015-05-14 14:48:03 +0100175static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700176 const PointerProperties* pointerProperties) {
177 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800178 ALOGE("Motion event has invalid action code 0x%x", action);
179 return false;
180 }
181 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000182 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700183 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800184 return false;
185 }
186 BitSet32 pointerIdBits;
187 for (size_t i = 0; i < pointerCount; i++) {
188 int32_t id = pointerProperties[i].id;
189 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700190 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
191 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800192 return false;
193 }
194 if (pointerIdBits.hasBit(id)) {
195 ALOGE("Motion event has duplicate pointer id %d", id);
196 return false;
197 }
198 pointerIdBits.markBit(id);
199 }
200 return true;
201}
202
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800203static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800205 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800206 return;
207 }
208
209 bool first = true;
210 Region::const_iterator cur = region.begin();
211 Region::const_iterator const tail = region.end();
212 while (cur != tail) {
213 if (first) {
214 first = false;
215 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800216 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800218 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800219 cur++;
220 }
221}
222
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500223static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
224 constexpr size_t maxEntries = 50; // max events to print
225 constexpr size_t skipBegin = maxEntries / 2;
226 const size_t skipEnd = queue.size() - maxEntries / 2;
227 // skip from maxEntries / 2 ... size() - maxEntries/2
228 // only print from 0 .. skipBegin and then from skipEnd .. size()
229
230 std::string dump;
231 for (size_t i = 0; i < queue.size(); i++) {
232 const DispatchEntry& entry = *queue[i];
233 if (i >= skipBegin && i < skipEnd) {
234 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
235 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
236 continue;
237 }
238 dump.append(INDENT4);
239 dump += entry.eventEntry->getDescription();
240 dump += StringPrintf(", seq=%" PRIu32
241 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
242 entry.seq, entry.targetFlags, entry.resolvedAction,
243 ns2ms(currentTime - entry.eventEntry->eventTime));
244 if (entry.deliveryTime != 0) {
245 // This entry was delivered, so add information on how long we've been waiting
246 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
247 }
248 dump.append("\n");
249 }
250 return dump;
251}
252
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700253/**
254 * Find the entry in std::unordered_map by key, and return it.
255 * If the entry is not found, return a default constructed entry.
256 *
257 * Useful when the entries are vectors, since an empty vector will be returned
258 * if the entry is not found.
259 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
260 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700261template <typename K, typename V>
262static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700263 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700264 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800265}
266
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700267/**
268 * Find the entry in std::unordered_map by value, and remove it.
269 * If more than one entry has the same value, then all matching
270 * key-value pairs will be removed.
271 *
272 * Return true if at least one value has been removed.
273 */
274template <typename K, typename V>
275static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
276 bool removed = false;
277 for (auto it = map.begin(); it != map.end();) {
278 if (it->second == value) {
279 it = map.erase(it);
280 removed = true;
281 } else {
282 it++;
283 }
284 }
285 return removed;
286}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800287
Vishnu Nair958da932020-08-21 17:12:37 -0700288/**
289 * Find the entry in std::unordered_map by key and return the value as an optional.
290 */
291template <typename K, typename V>
292static std::optional<V> getOptionalValueByKey(const std::unordered_map<K, V>& map, K key) {
293 auto it = map.find(key);
294 return it != map.end() ? std::optional<V>{it->second} : std::nullopt;
295}
296
chaviwaf87b3e2019-10-01 16:59:28 -0700297static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
298 if (first == second) {
299 return true;
300 }
301
302 if (first == nullptr || second == nullptr) {
303 return false;
304 }
305
306 return first->getToken() == second->getToken();
307}
308
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800309static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
310 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
311}
312
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000313static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700314 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000315 int32_t inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700316 if (inputTarget.useDefaultPointerTransform()) {
317 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700318 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
chaviw1ff3d1e2020-07-01 15:53:47 -0700319 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000320 }
321
322 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
323 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
324
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700325 std::vector<PointerCoords> pointerCoords;
326 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000327
328 // Use the first pointer information to normalize all other pointers. This could be any pointer
329 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700330 // uses the transform for the normalized pointer.
331 const ui::Transform& firstPointerTransform =
332 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
333 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000334
335 // Iterate through all pointers in the event to normalize against the first.
336 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
337 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
338 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700339 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000340
341 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700342 // First, apply the current pointer's transform to update the coordinates into
343 // window space.
344 pointerCoords[pointerIndex].transform(currTransform);
345 // Next, apply the inverse transform of the normalized coordinates so the
346 // current coordinates are transformed into the normalized coordinate space.
347 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000348 }
349
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700350 std::unique_ptr<MotionEntry> combinedMotionEntry =
351 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
352 motionEntry.deviceId, motionEntry.source,
353 motionEntry.displayId, motionEntry.policyFlags,
354 motionEntry.action, motionEntry.actionButton,
355 motionEntry.flags, motionEntry.metaState,
356 motionEntry.buttonState, motionEntry.classification,
357 motionEntry.edgeFlags, motionEntry.xPrecision,
358 motionEntry.yPrecision, motionEntry.xCursorPosition,
359 motionEntry.yCursorPosition, motionEntry.downTime,
360 motionEntry.pointerCount, motionEntry.pointerProperties,
361 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000362
363 if (motionEntry.injectionState) {
364 combinedMotionEntry->injectionState = motionEntry.injectionState;
365 combinedMotionEntry->injectionState->refCount += 1;
366 }
367
368 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700369 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
370 firstPointerTransform, inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000371 return dispatchEntry;
372}
373
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700374static void addGestureMonitors(const std::vector<Monitor>& monitors,
375 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
376 float yOffset = 0) {
377 if (monitors.empty()) {
378 return;
379 }
380 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
381 for (const Monitor& monitor : monitors) {
382 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
383 }
384}
385
Garfield Tan15601662020-09-22 15:32:38 -0700386static status_t openInputChannelPair(const std::string& name,
387 std::shared_ptr<InputChannel>& serverChannel,
388 std::unique_ptr<InputChannel>& clientChannel) {
389 std::unique_ptr<InputChannel> uniqueServerChannel;
390 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
391
392 serverChannel = std::move(uniqueServerChannel);
393 return result;
394}
395
Vishnu Nair958da932020-08-21 17:12:37 -0700396const char* InputDispatcher::typeToString(InputDispatcher::FocusResult result) {
397 switch (result) {
398 case InputDispatcher::FocusResult::OK:
399 return "Ok";
400 case InputDispatcher::FocusResult::NO_WINDOW:
401 return "Window not found";
402 case InputDispatcher::FocusResult::NOT_FOCUSABLE:
403 return "Window not focusable";
404 case InputDispatcher::FocusResult::NOT_VISIBLE:
405 return "Window not visible";
406 }
407}
408
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500409template <typename T>
410static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
411 if (lhs == nullptr && rhs == nullptr) {
412 return true;
413 }
414 if (lhs == nullptr || rhs == nullptr) {
415 return false;
416 }
417 return *lhs == *rhs;
418}
419
Michael Wrightd02c5b62014-02-10 15:10:22 -0800420// --- InputDispatcher ---
421
Garfield Tan00f511d2019-06-12 16:55:40 -0700422InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
423 : mPolicy(policy),
424 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700425 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800426 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700427 mAppSwitchSawKeyDown(false),
428 mAppSwitchDueTime(LONG_LONG_MAX),
429 mNextUnblockedEvent(nullptr),
430 mDispatchEnabled(false),
431 mDispatchFrozen(false),
432 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800433 // mInTouchMode will be initialized by the WindowManager to the default device config.
434 // To avoid leaking stack in case that call never comes, and for tests,
435 // initialize it here anyways.
436 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100437 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700438 mFocusedDisplayId(ADISPLAY_ID_DEFAULT) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800439 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800440 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800441
Yi Kong9b14ac62018-07-17 13:48:38 -0700442 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800443
444 policy->getDispatcherConfiguration(&mConfig);
445}
446
447InputDispatcher::~InputDispatcher() {
448 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800449 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800450
451 resetKeyRepeatLocked();
452 releasePendingEventLocked();
453 drainInboundQueueLocked();
454 }
455
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700456 while (!mConnectionsByFd.empty()) {
457 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700458 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800459 }
460}
461
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700462status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700463 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700464 return ALREADY_EXISTS;
465 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700466 mThread = std::make_unique<InputThread>(
467 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
468 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700469}
470
471status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700472 if (mThread && mThread->isCallingThread()) {
473 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700474 return INVALID_OPERATION;
475 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700476 mThread.reset();
477 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700478}
479
Michael Wrightd02c5b62014-02-10 15:10:22 -0800480void InputDispatcher::dispatchOnce() {
481 nsecs_t nextWakeupTime = LONG_LONG_MAX;
482 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800483 std::scoped_lock _l(mLock);
484 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800485
486 // Run a dispatch loop if there are no pending commands.
487 // The dispatch loop might enqueue commands to run afterwards.
488 if (!haveCommandsLocked()) {
489 dispatchOnceInnerLocked(&nextWakeupTime);
490 }
491
492 // Run all pending commands if there are any.
493 // If any commands were run then force the next poll to wake up immediately.
494 if (runCommandsLockedInterruptible()) {
495 nextWakeupTime = LONG_LONG_MIN;
496 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800497
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700498 // If we are still waiting for ack on some events,
499 // we might have to wake up earlier to check if an app is anr'ing.
500 const nsecs_t nextAnrCheck = processAnrsLocked();
501 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
502
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800503 // We are about to enter an infinitely long sleep, because we have no commands or
504 // pending or queued events
505 if (nextWakeupTime == LONG_LONG_MAX) {
506 mDispatcherEnteredIdle.notify_all();
507 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800508 } // release lock
509
510 // Wait for callback or timeout or wake. (make sure we round up, not down)
511 nsecs_t currentTime = now();
512 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
513 mLooper->pollOnce(timeoutMillis);
514}
515
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700516/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500517 * Raise ANR if there is no focused window.
518 * Before the ANR is raised, do a final state check:
519 * 1. The currently focused application must be the same one we are waiting for.
520 * 2. Ensure we still don't have a focused window.
521 */
522void InputDispatcher::processNoFocusedWindowAnrLocked() {
523 // Check if the application that we are waiting for is still focused.
524 std::shared_ptr<InputApplicationHandle> focusedApplication =
525 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
526 if (focusedApplication == nullptr ||
527 focusedApplication->getApplicationToken() !=
528 mAwaitedFocusedApplication->getApplicationToken()) {
529 // Unexpected because we should have reset the ANR timer when focused application changed
530 ALOGE("Waited for a focused window, but focused application has already changed to %s",
531 focusedApplication->getName().c_str());
532 return; // The focused application has changed.
533 }
534
535 const sp<InputWindowHandle>& focusedWindowHandle =
536 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
537 if (focusedWindowHandle != nullptr) {
538 return; // We now have a focused window. No need for ANR.
539 }
540 onAnrLocked(mAwaitedFocusedApplication);
541}
542
543/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700544 * Check if any of the connections' wait queues have events that are too old.
545 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
546 * Return the time at which we should wake up next.
547 */
548nsecs_t InputDispatcher::processAnrsLocked() {
549 const nsecs_t currentTime = now();
550 nsecs_t nextAnrCheck = LONG_LONG_MAX;
551 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
552 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
553 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500554 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700555 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500556 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700557 return LONG_LONG_MIN;
558 } else {
559 // Keep waiting
560 const nsecs_t millisRemaining = ns2ms(*mNoFocusedWindowTimeoutTime - currentTime);
561 ALOGW("Still no focused window. Will drop the event in %" PRId64 "ms", millisRemaining);
562 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
563 }
564 }
565
566 // Check if any connection ANRs are due
567 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
568 if (currentTime < nextAnrCheck) { // most likely scenario
569 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
570 }
571
572 // If we reached here, we have an unresponsive connection.
573 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
574 if (connection == nullptr) {
575 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
576 return nextAnrCheck;
577 }
578 connection->responsive = false;
579 // Stop waking up for this unresponsive connection
580 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -0500581 onAnrLocked(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700582 return LONG_LONG_MIN;
583}
584
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500585std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700586 sp<InputWindowHandle> window = getWindowHandleLocked(token);
587 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500588 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700589 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500590 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700591}
592
Michael Wrightd02c5b62014-02-10 15:10:22 -0800593void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
594 nsecs_t currentTime = now();
595
Jeff Browndc5992e2014-04-11 01:27:26 -0700596 // Reset the key repeat timer whenever normal dispatch is suspended while the
597 // device is in a non-interactive state. This is to ensure that we abort a key
598 // repeat if the device is just coming out of sleep.
599 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800600 resetKeyRepeatLocked();
601 }
602
603 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
604 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100605 if (DEBUG_FOCUS) {
606 ALOGD("Dispatch frozen. Waiting some more.");
607 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800608 return;
609 }
610
611 // Optimize latency of app switches.
612 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
613 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
614 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
615 if (mAppSwitchDueTime < *nextWakeupTime) {
616 *nextWakeupTime = mAppSwitchDueTime;
617 }
618
619 // Ready to start a new event.
620 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700621 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700622 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800623 if (isAppSwitchDue) {
624 // The inbound queue is empty so the app switch key we were waiting
625 // for will never arrive. Stop waiting for it.
626 resetPendingAppSwitchLocked(false);
627 isAppSwitchDue = false;
628 }
629
630 // Synthesize a key repeat if appropriate.
631 if (mKeyRepeatState.lastKeyEntry) {
632 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
633 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
634 } else {
635 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
636 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
637 }
638 }
639 }
640
641 // Nothing to do if there is no pending event.
642 if (!mPendingEvent) {
643 return;
644 }
645 } else {
646 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700647 mPendingEvent = mInboundQueue.front();
648 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800649 traceInboundQueueLengthLocked();
650 }
651
652 // Poke user activity for this event.
653 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700654 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800655 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800656 }
657
658 // Now we have an event to dispatch.
659 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700660 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800661 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700662 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800663 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700664 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800665 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700666 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800667 }
668
669 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700670 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800671 }
672
673 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700674 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700675 const ConfigurationChangedEntry& typedEntry =
676 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700677 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700678 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700679 break;
680 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800681
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700682 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700683 const DeviceResetEntry& typedEntry =
684 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700685 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700686 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700687 break;
688 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800689
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100690 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700691 std::shared_ptr<FocusEntry> typedEntry =
692 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100693 dispatchFocusLocked(currentTime, typedEntry);
694 done = true;
695 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
696 break;
697 }
698
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700699 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700700 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700701 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700702 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700703 resetPendingAppSwitchLocked(true);
704 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700705 } else if (dropReason == DropReason::NOT_DROPPED) {
706 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700707 }
708 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700709 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700710 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700711 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700712 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
713 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700714 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700715 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700716 break;
717 }
718
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700719 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700720 std::shared_ptr<MotionEntry> motionEntry =
721 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700722 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
723 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800724 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700725 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700726 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700727 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700728 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
729 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700730 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700731 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700732 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800733 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800734 }
735
736 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700737 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700738 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800739 }
Michael Wright3a981722015-06-10 15:26:13 +0100740 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800741
742 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700743 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800744 }
745}
746
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700747/**
748 * Return true if the events preceding this incoming motion event should be dropped
749 * Return false otherwise (the default behaviour)
750 */
751bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700752 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700753 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700754
755 // Optimize case where the current application is unresponsive and the user
756 // decides to touch a window in a different application.
757 // If the application takes too long to catch up then we drop all events preceding
758 // the touch into the other window.
759 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700760 int32_t displayId = motionEntry.displayId;
761 int32_t x = static_cast<int32_t>(
762 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
763 int32_t y = static_cast<int32_t>(
764 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
765 sp<InputWindowHandle> touchedWindowHandle =
766 findTouchedWindowAtLocked(displayId, x, y, nullptr);
767 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700768 touchedWindowHandle->getApplicationToken() !=
769 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700770 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700771 ALOGI("Pruning input queue because user touched a different application while waiting "
772 "for %s",
773 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700774 return true;
775 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700776
777 // Alternatively, maybe there's a gesture monitor that could handle this event
778 std::vector<TouchedMonitor> gestureMonitors =
779 findTouchedGestureMonitorsLocked(displayId, {});
780 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
781 sp<Connection> connection =
782 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000783 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700784 // This monitor could take more input. Drop all events preceding this
785 // event, so that gesture monitor could get a chance to receive the stream
786 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
787 "responsive gesture monitor that may handle the event",
788 mAwaitedFocusedApplication->getName().c_str());
789 return true;
790 }
791 }
792 }
793
794 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
795 // yet been processed by some connections, the dispatcher will wait for these motion
796 // events to be processed before dispatching the key event. This is because these motion events
797 // may cause a new window to be launched, which the user might expect to receive focus.
798 // To prevent waiting forever for such events, just send the key to the currently focused window
799 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
800 ALOGD("Received a new pointer down event, stop waiting for events to process and "
801 "just send the pending key event to the focused window.");
802 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700803 }
804 return false;
805}
806
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700807bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700808 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700809 mInboundQueue.push_back(std::move(newEntry));
810 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800811 traceInboundQueueLengthLocked();
812
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700813 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700814 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700815 // Optimize app switch latency.
816 // If the application takes too long to catch up then we drop all events preceding
817 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700818 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700819 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700820 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700821 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700822 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700823 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800824#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700825 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800826#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700827 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700828 mAppSwitchSawKeyDown = false;
829 needWake = true;
830 }
831 }
832 }
833 break;
834 }
835
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700836 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700837 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
838 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700839 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800840 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700841 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800842 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100843 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700844 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
845 break;
846 }
847 case EventEntry::Type::CONFIGURATION_CHANGED:
848 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700849 // nothing to do
850 break;
851 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800852 }
853
854 return needWake;
855}
856
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700857void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700858 mRecentQueue.push_back(entry);
859 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700860 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800861 }
862}
863
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700864sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700865 int32_t y, TouchState* touchState,
866 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700867 bool addPortalWindows) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700868 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
869 LOG_ALWAYS_FATAL(
870 "Must provide a valid touch state if adding portal windows or outside targets");
871 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800872 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700873 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800874 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800875 const InputWindowInfo* windowInfo = windowHandle->getInfo();
876 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100877 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800878
879 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100880 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
881 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
882 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800883 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800884 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700885 if (portalToDisplayId != ADISPLAY_ID_NONE &&
886 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800887 if (addPortalWindows) {
888 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700889 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800890 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700891 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700892 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800893 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800894 // Found window.
895 return windowHandle;
896 }
897 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800898
Michael Wright44753b12020-07-08 13:48:11 +0100899 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700900 touchState->addOrUpdateWindow(windowHandle,
901 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
902 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800903 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800904 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800905 }
906 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700907 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800908}
909
Garfield Tane84e6f92019-08-29 17:28:41 -0700910std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700911 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000912 std::vector<TouchedMonitor> touchedMonitors;
913
914 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
915 addGestureMonitors(monitors, touchedMonitors);
916 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
917 const InputWindowInfo* windowInfo = portalWindow->getInfo();
918 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700919 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
920 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000921 }
922 return touchedMonitors;
923}
924
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700925void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800926 const char* reason;
927 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700928 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800929#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700930 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800931#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700932 reason = "inbound event was dropped because the policy consumed it";
933 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700934 case DropReason::DISABLED:
935 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700936 ALOGI("Dropped event because input dispatch is disabled.");
937 }
938 reason = "inbound event was dropped because input dispatch is disabled";
939 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700940 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700941 ALOGI("Dropped event because of pending overdue app switch.");
942 reason = "inbound event was dropped because of pending overdue app switch";
943 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700944 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700945 ALOGI("Dropped event because the current application is not responding and the user "
946 "has started interacting with a different application.");
947 reason = "inbound event was dropped because the current application is not responding "
948 "and the user has started interacting with a different application";
949 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700950 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700951 ALOGI("Dropped event because it is stale.");
952 reason = "inbound event was dropped because it is stale";
953 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700954 case DropReason::NOT_DROPPED: {
955 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700956 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700957 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800958 }
959
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700960 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700961 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800962 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
963 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700964 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800965 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700966 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700967 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
968 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700969 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
970 synthesizeCancelationEventsForAllConnectionsLocked(options);
971 } else {
972 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
973 synthesizeCancelationEventsForAllConnectionsLocked(options);
974 }
975 break;
976 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100977 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700978 case EventEntry::Type::CONFIGURATION_CHANGED:
979 case EventEntry::Type::DEVICE_RESET: {
980 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
981 break;
982 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800983 }
984}
985
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800986static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700987 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
988 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800989}
990
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700991bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
992 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
993 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
994 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800995}
996
997bool InputDispatcher::isAppSwitchPendingLocked() {
998 return mAppSwitchDueTime != LONG_LONG_MAX;
999}
1000
1001void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1002 mAppSwitchDueTime = LONG_LONG_MAX;
1003
1004#if DEBUG_APP_SWITCH
1005 if (handled) {
1006 ALOGD("App switch has arrived.");
1007 } else {
1008 ALOGD("App switch was abandoned.");
1009 }
1010#endif
1011}
1012
Michael Wrightd02c5b62014-02-10 15:10:22 -08001013bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001014 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001015}
1016
1017bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001018 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001019 return false;
1020 }
1021
1022 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001023 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001024 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001025 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001026 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001027
1028 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001029 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001030 return true;
1031}
1032
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001033void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1034 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001035}
1036
1037void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001038 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001039 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001040 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001041 releaseInboundEventLocked(entry);
1042 }
1043 traceInboundQueueLengthLocked();
1044}
1045
1046void InputDispatcher::releasePendingEventLocked() {
1047 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001048 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001049 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001050 }
1051}
1052
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001053void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001054 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001055 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001056#if DEBUG_DISPATCH_CYCLE
1057 ALOGD("Injected inbound event was dropped.");
1058#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001059 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001060 }
1061 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001062 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001063 }
1064 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001065}
1066
1067void InputDispatcher::resetKeyRepeatLocked() {
1068 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001069 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001070 }
1071}
1072
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001073std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1074 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001075
Michael Wright2e732952014-09-24 13:26:59 -07001076 uint32_t policyFlags = entry->policyFlags &
1077 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001078
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001079 std::shared_ptr<KeyEntry> newEntry =
1080 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1081 entry->source, entry->displayId, policyFlags, entry->action,
1082 entry->flags, entry->keyCode, entry->scanCode,
1083 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001084
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001085 newEntry->syntheticRepeat = true;
1086 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001087 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001088 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001089}
1090
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001091bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001092 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001093#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001094 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001095#endif
1096
1097 // Reset key repeating in case a keyboard device was added or removed or something.
1098 resetKeyRepeatLocked();
1099
1100 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001101 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1102 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001103 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001104 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001105 return true;
1106}
1107
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001108bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1109 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001110#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001111 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1112 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001113#endif
1114
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001115 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001116 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001117 synthesizeCancelationEventsForAllConnectionsLocked(options);
1118 return true;
1119}
1120
Vishnu Nairad321cd2020-08-20 16:40:21 -07001121void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001122 std::string_view reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001123 if (mPendingEvent != nullptr) {
1124 // Move the pending event to the front of the queue. This will give the chance
1125 // for the pending event to get dispatched to the newly focused window
1126 mInboundQueue.push_front(mPendingEvent);
1127 mPendingEvent = nullptr;
1128 }
1129
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001130 std::unique_ptr<FocusEntry> focusEntry =
1131 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1132 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001133
1134 // This event should go to the front of the queue, but behind all other focus events
1135 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001136 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001137 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001138 [](const std::shared_ptr<EventEntry>& event) {
1139 return event->type == EventEntry::Type::FOCUS;
1140 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001141
1142 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001143 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001144}
1145
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001146void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001147 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001148 if (channel == nullptr) {
1149 return; // Window has gone away
1150 }
1151 InputTarget target;
1152 target.inputChannel = channel;
1153 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1154 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001155 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1156 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001157 std::string reason = std::string("reason=").append(entry->reason);
1158 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001159 dispatchEventLocked(currentTime, entry, {target});
1160}
1161
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001162bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001163 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001164 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001165 if (!entry->dispatchInProgress) {
1166 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1167 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1168 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1169 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001170 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001171 // We have seen two identical key downs in a row which indicates that the device
1172 // driver is automatically generating key repeats itself. We take note of the
1173 // repeat here, but we disable our own next key repeat timer since it is clear that
1174 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001175 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1176 // Make sure we don't get key down from a different device. If a different
1177 // device Id has same key pressed down, the new device Id will replace the
1178 // current one to hold the key repeat with repeat count reset.
1179 // In the future when got a KEY_UP on the device id, drop it and do not
1180 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001181 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1182 resetKeyRepeatLocked();
1183 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1184 } else {
1185 // Not a repeat. Save key down state in case we do see a repeat later.
1186 resetKeyRepeatLocked();
1187 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1188 }
1189 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001190 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1191 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001192 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001193#if DEBUG_INBOUND_EVENT_DETAILS
1194 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1195#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001196 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001197 resetKeyRepeatLocked();
1198 }
1199
1200 if (entry->repeatCount == 1) {
1201 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1202 } else {
1203 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1204 }
1205
1206 entry->dispatchInProgress = true;
1207
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001208 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001209 }
1210
1211 // Handle case where the policy asked us to try again later last time.
1212 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1213 if (currentTime < entry->interceptKeyWakeupTime) {
1214 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1215 *nextWakeupTime = entry->interceptKeyWakeupTime;
1216 }
1217 return false; // wait until next wakeup
1218 }
1219 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1220 entry->interceptKeyWakeupTime = 0;
1221 }
1222
1223 // Give the policy a chance to intercept the key.
1224 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1225 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001226 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001227 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001228 sp<IBinder> focusedWindowToken =
1229 getValueByKey(mFocusedWindowTokenByDisplay, getTargetDisplayId(*entry));
1230 if (focusedWindowToken != nullptr) {
1231 commandEntry->inputChannel = getInputChannelLocked(focusedWindowToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001232 }
1233 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001234 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001235 return false; // wait for the command to run
1236 } else {
1237 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1238 }
1239 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001240 if (*dropReason == DropReason::NOT_DROPPED) {
1241 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001242 }
1243 }
1244
1245 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001246 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001247 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001248 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1249 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001250 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001251 return true;
1252 }
1253
1254 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001255 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001256 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001257 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001258 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001259 return false;
1260 }
1261
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001262 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001263 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001264 return true;
1265 }
1266
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001267 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001268 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001269
1270 // Dispatch the key.
1271 dispatchEventLocked(currentTime, entry, inputTargets);
1272 return true;
1273}
1274
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001275void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001276#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001277 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001278 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1279 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001280 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1281 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1282 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001283#endif
1284}
1285
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001286bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001287 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001288 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001289 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001290 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001291 entry->dispatchInProgress = true;
1292
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001293 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001294 }
1295
1296 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001297 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001298 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001299 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1300 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001301 return true;
1302 }
1303
1304 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1305
1306 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001307 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001308
1309 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001310 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001311 if (isPointerEvent) {
1312 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001313 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001314 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001315 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001316 } else {
1317 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001318 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001319 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001320 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001321 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001322 return false;
1323 }
1324
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001325 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001326 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001327 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1328 return true;
1329 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001330 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001331 CancelationOptions::Mode mode(isPointerEvent
1332 ? CancelationOptions::CANCEL_POINTER_EVENTS
1333 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1334 CancelationOptions options(mode, "input event injection failed");
1335 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001336 return true;
1337 }
1338
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001339 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001340 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001341
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001342 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001343 std::unordered_map<int32_t, TouchState>::iterator it =
1344 mTouchStatesByDisplay.find(entry->displayId);
1345 if (it != mTouchStatesByDisplay.end()) {
1346 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001347 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001348 // The event has gone through these portal windows, so we add monitoring targets of
1349 // the corresponding displays as well.
1350 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001351 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001352 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001353 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001354 }
1355 }
1356 }
1357 }
1358
Michael Wrightd02c5b62014-02-10 15:10:22 -08001359 // Dispatch the motion.
1360 if (conflictingPointerActions) {
1361 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001362 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001363 synthesizeCancelationEventsForAllConnectionsLocked(options);
1364 }
1365 dispatchEventLocked(currentTime, entry, inputTargets);
1366 return true;
1367}
1368
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001369void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001370#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001371 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001372 ", policyFlags=0x%x, "
1373 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1374 "metaState=0x%x, buttonState=0x%x,"
1375 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001376 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1377 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1378 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001379
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001380 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001381 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001382 "x=%f, y=%f, pressure=%f, size=%f, "
1383 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1384 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001385 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1386 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1387 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1388 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1389 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1390 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1391 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1392 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1393 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1394 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001395 }
1396#endif
1397}
1398
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001399void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1400 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001401 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001402 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001403#if DEBUG_DISPATCH_CYCLE
1404 ALOGD("dispatchEventToCurrentInputTargets");
1405#endif
1406
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001407 updateInteractionTokensLocked(*eventEntry, inputTargets);
1408
Michael Wrightd02c5b62014-02-10 15:10:22 -08001409 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1410
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001411 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001412
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001413 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001414 sp<Connection> connection =
1415 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001416 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001417 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001418 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001419 if (DEBUG_FOCUS) {
1420 ALOGD("Dropping event delivery to target with channel '%s' because it "
1421 "is no longer registered with the input dispatcher.",
1422 inputTarget.inputChannel->getName().c_str());
1423 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001424 }
1425 }
1426}
1427
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001428void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1429 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1430 // If the policy decides to close the app, we will get a channel removal event via
1431 // unregisterInputChannel, and will clean up the connection that way. We are already not
1432 // sending new pointers to the connection when it blocked, but focused events will continue to
1433 // pile up.
1434 ALOGW("Canceling events for %s because it is unresponsive",
1435 connection->inputChannel->getName().c_str());
1436 if (connection->status == Connection::STATUS_NORMAL) {
1437 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1438 "application not responding");
1439 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001440 }
1441}
1442
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001443void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001444 if (DEBUG_FOCUS) {
1445 ALOGD("Resetting ANR timeouts.");
1446 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001447
1448 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001449 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001450 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001451}
1452
Tiger Huang721e26f2018-07-24 22:26:19 +08001453/**
1454 * Get the display id that the given event should go to. If this event specifies a valid display id,
1455 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1456 * Focused display is the display that the user most recently interacted with.
1457 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001458int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001459 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001460 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001461 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001462 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1463 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001464 break;
1465 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001466 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001467 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1468 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001469 break;
1470 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001471 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001472 case EventEntry::Type::CONFIGURATION_CHANGED:
1473 case EventEntry::Type::DEVICE_RESET: {
1474 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001475 return ADISPLAY_ID_NONE;
1476 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001477 }
1478 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1479}
1480
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001481bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1482 const char* focusedWindowName) {
1483 if (mAnrTracker.empty()) {
1484 // already processed all events that we waited for
1485 mKeyIsWaitingForEventsTimeout = std::nullopt;
1486 return false;
1487 }
1488
1489 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1490 // Start the timer
1491 ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
1492 "focus to change",
1493 focusedWindowName);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001494 mKeyIsWaitingForEventsTimeout = currentTime +
1495 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1496 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001497 return true;
1498 }
1499
1500 // We still have pending events, and already started the timer
1501 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1502 return true; // Still waiting
1503 }
1504
1505 // Waited too long, and some connection still hasn't processed all motions
1506 // Just send the key to the focused window
1507 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1508 focusedWindowName);
1509 mKeyIsWaitingForEventsTimeout = std::nullopt;
1510 return false;
1511}
1512
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001513InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1514 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1515 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001516 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001517
Tiger Huang721e26f2018-07-24 22:26:19 +08001518 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001519 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001520 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001521 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1522
Michael Wrightd02c5b62014-02-10 15:10:22 -08001523 // If there is no currently focused window and no focused application
1524 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001525 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1526 ALOGI("Dropping %s event because there is no focused window or focused application in "
1527 "display %" PRId32 ".",
1528 EventEntry::typeToString(entry.type), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001529 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001530 }
1531
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001532 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1533 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1534 // start interacting with another application via touch (app switch). This code can be removed
1535 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1536 // an app is expected to have a focused window.
1537 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1538 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1539 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001540 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1541 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1542 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001543 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001544 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001545 ALOGW("Waiting because no window has focus but %s may eventually add a "
1546 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001547 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001548 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001549 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001550 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1551 // Already raised ANR. Drop the event
1552 ALOGE("Dropping %s event because there is no focused window",
1553 EventEntry::typeToString(entry.type));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001554 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001555 } else {
1556 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001557 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001558 }
1559 }
1560
1561 // we have a valid, non-null focused window
1562 resetNoFocusedWindowTimeoutLocked();
1563
Michael Wrightd02c5b62014-02-10 15:10:22 -08001564 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001565 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001566 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001567 }
1568
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001569 if (focusedWindowHandle->getInfo()->paused) {
1570 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001571 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001572 }
1573
1574 // If the event is a key event, then we must wait for all previous events to
1575 // complete before delivering it because previous events may have the
1576 // side-effect of transferring focus to a different window and we want to
1577 // ensure that the following keys are sent to the new window.
1578 //
1579 // Suppose the user touches a button in a window then immediately presses "A".
1580 // If the button causes a pop-up window to appear then we want to ensure that
1581 // the "A" key is delivered to the new pop-up window. This is because users
1582 // often anticipate pending UI changes when typing on a keyboard.
1583 // To obtain this behavior, we must serialize key events with respect to all
1584 // prior input events.
1585 if (entry.type == EventEntry::Type::KEY) {
1586 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1587 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001588 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001589 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001590 }
1591
1592 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001593 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001594 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1595 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001596
1597 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001598 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001599}
1600
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001601/**
1602 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1603 * that are currently unresponsive.
1604 */
1605std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1606 const std::vector<TouchedMonitor>& monitors) const {
1607 std::vector<TouchedMonitor> responsiveMonitors;
1608 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1609 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1610 sp<Connection> connection = getConnectionLocked(
1611 monitor.monitor.inputChannel->getConnectionToken());
1612 if (connection == nullptr) {
1613 ALOGE("Could not find connection for monitor %s",
1614 monitor.monitor.inputChannel->getName().c_str());
1615 return false;
1616 }
1617 if (!connection->responsive) {
1618 ALOGW("Unresponsive monitor %s will not get the new gesture",
1619 connection->inputChannel->getName().c_str());
1620 return false;
1621 }
1622 return true;
1623 });
1624 return responsiveMonitors;
1625}
1626
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001627InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1628 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1629 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001630 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001631 enum InjectionPermission {
1632 INJECTION_PERMISSION_UNKNOWN,
1633 INJECTION_PERMISSION_GRANTED,
1634 INJECTION_PERMISSION_DENIED
1635 };
1636
Michael Wrightd02c5b62014-02-10 15:10:22 -08001637 // For security reasons, we defer updating the touch state until we are sure that
1638 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001639 int32_t displayId = entry.displayId;
1640 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001641 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1642
1643 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001644 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001645 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001646 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1647 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001648
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001649 // Copy current touch state into tempTouchState.
1650 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1651 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001652 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001653 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001654 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1655 mTouchStatesByDisplay.find(displayId);
1656 if (oldStateIt != mTouchStatesByDisplay.end()) {
1657 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001658 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001659 }
1660
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001661 bool isSplit = tempTouchState.split;
1662 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1663 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1664 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001665 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1666 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1667 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1668 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1669 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001670 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001671 bool wrongDevice = false;
1672 if (newGesture) {
1673 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001674 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001675 ALOGI("Dropping event because a pointer for a different device is already down "
1676 "in display %" PRId32,
1677 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001678 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001679 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001680 switchedDevice = false;
1681 wrongDevice = true;
1682 goto Failed;
1683 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001684 tempTouchState.reset();
1685 tempTouchState.down = down;
1686 tempTouchState.deviceId = entry.deviceId;
1687 tempTouchState.source = entry.source;
1688 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001689 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001690 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001691 ALOGI("Dropping move event because a pointer for a different device is already active "
1692 "in display %" PRId32,
1693 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001694 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001695 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001696 switchedDevice = false;
1697 wrongDevice = true;
1698 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001699 }
1700
1701 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1702 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1703
Garfield Tan00f511d2019-06-12 16:55:40 -07001704 int32_t x;
1705 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001706 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001707 // Always dispatch mouse events to cursor position.
1708 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001709 x = int32_t(entry.xCursorPosition);
1710 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001711 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001712 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1713 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001714 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001715 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001716 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001717 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1718 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001719
1720 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001721 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001722 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001723
Michael Wrightd02c5b62014-02-10 15:10:22 -08001724 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001725 if (newTouchedWindowHandle != nullptr &&
1726 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001727 // New window supports splitting, but we should never split mouse events.
1728 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001729 } else if (isSplit) {
1730 // New window does not support splitting but we have already split events.
1731 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001732 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001733 }
1734
1735 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001736 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001737 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001738 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001739 }
1740
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001741 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1742 ALOGI("Not sending touch event to %s because it is paused",
1743 newTouchedWindowHandle->getName().c_str());
1744 newTouchedWindowHandle = nullptr;
1745 }
1746
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001747 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001748 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001749 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1750 if (!isResponsive) {
1751 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001752 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1753 newTouchedWindowHandle = nullptr;
1754 }
1755 }
1756
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001757 // Drop events that can't be trusted due to occlusion
1758 if (newTouchedWindowHandle != nullptr &&
1759 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1760 TouchOcclusionInfo occlusionInfo =
1761 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
1762 // The order of the operands in the 'if' below is important because even if the feature
1763 // is not BLOCK we want isTouchTrustedLocked() to execute in order to log details to
1764 // logcat.
1765 if (!isTouchTrustedLocked(occlusionInfo) &&
1766 mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1767 ALOGW("Dropping untrusted touch event due to %s/%d",
1768 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1769 newTouchedWindowHandle = nullptr;
1770 }
1771 }
1772
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001773 // Also don't send the new touch event to unresponsive gesture monitors
1774 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1775
Michael Wright3dd60e22019-03-27 22:06:44 +00001776 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1777 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001778 "(%d, %d) in display %" PRId32 ".",
1779 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001780 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001781 goto Failed;
1782 }
1783
1784 if (newTouchedWindowHandle != nullptr) {
1785 // Set target flags.
1786 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1787 if (isSplit) {
1788 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001789 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001790 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1791 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1792 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1793 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1794 }
1795
1796 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07001797 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
1798 newHoverWindowHandle = nullptr;
1799 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001800 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00001801 }
1802
1803 // Update the temporary touch state.
1804 BitSet32 pointerIds;
1805 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001806 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001807 pointerIds.markBit(pointerId);
1808 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001809 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001810 }
1811
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001812 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001813 } else {
1814 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1815
1816 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001817 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001818 if (DEBUG_FOCUS) {
1819 ALOGD("Dropping event because the pointer is not down or we previously "
1820 "dropped the pointer down event in display %" PRId32,
1821 displayId);
1822 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001823 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001824 goto Failed;
1825 }
1826
1827 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001828 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001829 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001830 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1831 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001832
1833 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001834 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07001835 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001836 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1837 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001838 if (DEBUG_FOCUS) {
1839 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1840 oldTouchedWindowHandle->getName().c_str(),
1841 newTouchedWindowHandle->getName().c_str(), displayId);
1842 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001843 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001844 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1845 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1846 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001847
1848 // Make a slippery entrance into the new window.
1849 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1850 isSplit = true;
1851 }
1852
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001853 int32_t targetFlags =
1854 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001855 if (isSplit) {
1856 targetFlags |= InputTarget::FLAG_SPLIT;
1857 }
1858 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1859 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1860 }
1861
1862 BitSet32 pointerIds;
1863 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001864 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001865 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001866 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001867 }
1868 }
1869 }
1870
1871 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07001872 // Let the previous window know that the hover sequence is over, unless we already did it
1873 // when dispatching it as is to newTouchedWindowHandle.
1874 if (mLastHoverWindowHandle != nullptr &&
1875 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
1876 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001877#if DEBUG_HOVER
1878 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001879 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001880#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001881 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1882 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001883 }
1884
Garfield Tandf26e862020-07-01 20:18:19 -07001885 // Let the new window know that the hover sequence is starting, unless we already did it
1886 // when dispatching it as is to newTouchedWindowHandle.
1887 if (newHoverWindowHandle != nullptr &&
1888 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
1889 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001890#if DEBUG_HOVER
1891 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001892 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001893#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001894 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1895 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1896 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001897 }
1898 }
1899
1900 // Check permission to inject into all touched foreground windows and ensure there
1901 // is at least one touched foreground window.
1902 {
1903 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001904 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001905 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1906 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001907 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001908 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001909 injectionPermission = INJECTION_PERMISSION_DENIED;
1910 goto Failed;
1911 }
1912 }
1913 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001914 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00001915 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001916 ALOGI("Dropping event because there is no touched foreground window in display "
1917 "%" PRId32 " or gesture monitor to receive it.",
1918 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001919 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920 goto Failed;
1921 }
1922
1923 // Permission granted to injection into all touched foreground windows.
1924 injectionPermission = INJECTION_PERMISSION_GRANTED;
1925 }
1926
1927 // Check whether windows listening for outside touches are owned by the same UID. If it is
1928 // set the policy flag that we will not reveal coordinate information to this window.
1929 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1930 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001931 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001932 if (foregroundWindowHandle) {
1933 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001934 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001935 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1936 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1937 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001938 tempTouchState.addOrUpdateWindow(inputWindowHandle,
1939 InputTarget::FLAG_ZERO_COORDS,
1940 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001941 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001942 }
1943 }
1944 }
1945 }
1946
Michael Wrightd02c5b62014-02-10 15:10:22 -08001947 // If this is the first pointer going down and the touched window has a wallpaper
1948 // then also add the touched wallpaper windows so they are locked in for the duration
1949 // of the touch gesture.
1950 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1951 // engine only supports touch events. We would need to add a mechanism similar
1952 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1953 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1954 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001955 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001956 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001957 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001958 getWindowHandlesLocked(displayId);
1959 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001960 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001961 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01001962 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001963 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001964 .addOrUpdateWindow(windowHandle,
1965 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1966 InputTarget::
1967 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1968 InputTarget::FLAG_DISPATCH_AS_IS,
1969 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001970 }
1971 }
1972 }
1973 }
1974
1975 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001976 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001977
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001978 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001979 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001980 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001981 }
1982
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001983 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001984 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001985 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00001986 }
1987
Michael Wrightd02c5b62014-02-10 15:10:22 -08001988 // Drop the outside or hover touch windows since we will not care about them
1989 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001990 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001991
1992Failed:
1993 // Check injection permission once and for all.
1994 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001995 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001996 injectionPermission = INJECTION_PERMISSION_GRANTED;
1997 } else {
1998 injectionPermission = INJECTION_PERMISSION_DENIED;
1999 }
2000 }
2001
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002002 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2003 return injectionResult;
2004 }
2005
Michael Wrightd02c5b62014-02-10 15:10:22 -08002006 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002007 if (!wrongDevice) {
2008 if (switchedDevice) {
2009 if (DEBUG_FOCUS) {
2010 ALOGD("Conflicting pointer actions: Switched to a different device.");
2011 }
2012 *outConflictingPointerActions = true;
2013 }
2014
2015 if (isHoverAction) {
2016 // Started hovering, therefore no longer down.
2017 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002018 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002019 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2020 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002021 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002022 *outConflictingPointerActions = true;
2023 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002024 tempTouchState.reset();
2025 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2026 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2027 tempTouchState.deviceId = entry.deviceId;
2028 tempTouchState.source = entry.source;
2029 tempTouchState.displayId = displayId;
2030 }
2031 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2032 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2033 // All pointers up or canceled.
2034 tempTouchState.reset();
2035 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2036 // First pointer went down.
2037 if (oldState && oldState->down) {
2038 if (DEBUG_FOCUS) {
2039 ALOGD("Conflicting pointer actions: Down received while already down.");
2040 }
2041 *outConflictingPointerActions = true;
2042 }
2043 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2044 // One pointer went up.
2045 if (isSplit) {
2046 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2047 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002048
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002049 for (size_t i = 0; i < tempTouchState.windows.size();) {
2050 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2051 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2052 touchedWindow.pointerIds.clearBit(pointerId);
2053 if (touchedWindow.pointerIds.isEmpty()) {
2054 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2055 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002056 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002057 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002058 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002059 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002060 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002061 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002062
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002063 // Save changes unless the action was scroll in which case the temporary touch
2064 // state was only valid for this one action.
2065 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2066 if (tempTouchState.displayId >= 0) {
2067 mTouchStatesByDisplay[displayId] = tempTouchState;
2068 } else {
2069 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002070 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002071 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002072
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002073 // Update hover state.
2074 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002075 }
2076
Michael Wrightd02c5b62014-02-10 15:10:22 -08002077 return injectionResult;
2078}
2079
2080void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002081 int32_t targetFlags, BitSet32 pointerIds,
2082 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002083 std::vector<InputTarget>::iterator it =
2084 std::find_if(inputTargets.begin(), inputTargets.end(),
2085 [&windowHandle](const InputTarget& inputTarget) {
2086 return inputTarget.inputChannel->getConnectionToken() ==
2087 windowHandle->getToken();
2088 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002089
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002090 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002091
2092 if (it == inputTargets.end()) {
2093 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002094 std::shared_ptr<InputChannel> inputChannel =
2095 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002096 if (inputChannel == nullptr) {
2097 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2098 return;
2099 }
2100 inputTarget.inputChannel = inputChannel;
2101 inputTarget.flags = targetFlags;
2102 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2103 inputTargets.push_back(inputTarget);
2104 it = inputTargets.end() - 1;
2105 }
2106
2107 ALOG_ASSERT(it->flags == targetFlags);
2108 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2109
chaviw1ff3d1e2020-07-01 15:53:47 -07002110 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002111}
2112
Michael Wright3dd60e22019-03-27 22:06:44 +00002113void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002114 int32_t displayId, float xOffset,
2115 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002116 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2117 mGlobalMonitorsByDisplay.find(displayId);
2118
2119 if (it != mGlobalMonitorsByDisplay.end()) {
2120 const std::vector<Monitor>& monitors = it->second;
2121 for (const Monitor& monitor : monitors) {
2122 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002123 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002124 }
2125}
2126
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002127void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2128 float yOffset,
2129 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002130 InputTarget target;
2131 target.inputChannel = monitor.inputChannel;
2132 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002133 ui::Transform t;
2134 t.set(xOffset, yOffset);
2135 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002136 inputTargets.push_back(target);
2137}
2138
Michael Wrightd02c5b62014-02-10 15:10:22 -08002139bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002140 const InjectionState* injectionState) {
2141 if (injectionState &&
2142 (windowHandle == nullptr ||
2143 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2144 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002145 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002146 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002147 "owned by uid %d",
2148 injectionState->injectorPid, injectionState->injectorUid,
2149 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002150 } else {
2151 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002152 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002153 }
2154 return false;
2155 }
2156 return true;
2157}
2158
Robert Carrc9bf1d32020-04-13 17:21:08 -07002159/**
2160 * Indicate whether one window handle should be considered as obscuring
2161 * another window handle. We only check a few preconditions. Actually
2162 * checking the bounds is left to the caller.
2163 */
2164static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2165 const sp<InputWindowHandle>& otherHandle) {
2166 // Compare by token so cloned layers aren't counted
2167 if (haveSameToken(windowHandle, otherHandle)) {
2168 return false;
2169 }
2170 auto info = windowHandle->getInfo();
2171 auto otherInfo = otherHandle->getInfo();
2172 if (!otherInfo->visible) {
2173 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002174 } else if (info->ownerUid == otherInfo->ownerUid) {
2175 // If ownerUid is the same we don't generate occlusion events as there
2176 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002177 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002178 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002179 return false;
2180 } else if (otherInfo->displayId != info->displayId) {
2181 return false;
2182 }
2183 return true;
2184}
2185
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002186/**
2187 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2188 * untrusted, one should check:
2189 *
2190 * 1. If result.hasBlockingOcclusion is true.
2191 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2192 * BLOCK_UNTRUSTED.
2193 *
2194 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2195 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2196 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2197 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2198 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2199 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2200 *
2201 * If neither of those is true, then it means the touch can be allowed.
2202 */
2203InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2204 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
2205 int32_t displayId = windowHandle->getInfo()->displayId;
2206 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2207 TouchOcclusionInfo info;
2208 info.hasBlockingOcclusion = false;
2209 info.obscuringOpacity = 0;
2210 info.obscuringUid = -1;
2211 std::map<int32_t, float> opacityByUid;
2212 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2213 if (windowHandle == otherHandle) {
2214 break; // All future windows are below us. Exit early.
2215 }
2216 const InputWindowInfo* otherInfo = otherHandle->getInfo();
2217 if (canBeObscuredBy(windowHandle, otherHandle) &&
2218 windowHandle->getInfo()->ownerUid != otherInfo->ownerUid &&
2219 otherInfo->frameContainsPoint(x, y)) {
2220 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2221 // we perform the checks below to see if the touch can be propagated or not based on the
2222 // window's touch occlusion mode
2223 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2224 info.hasBlockingOcclusion = true;
2225 info.obscuringUid = otherInfo->ownerUid;
2226 info.obscuringPackage = otherInfo->packageName;
2227 break;
2228 }
2229 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2230 uint32_t uid = otherInfo->ownerUid;
2231 float opacity =
2232 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2233 // Given windows A and B:
2234 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2235 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2236 opacityByUid[uid] = opacity;
2237 if (opacity > info.obscuringOpacity) {
2238 info.obscuringOpacity = opacity;
2239 info.obscuringUid = uid;
2240 info.obscuringPackage = otherInfo->packageName;
2241 }
2242 }
2243 }
2244 }
2245 return info;
2246}
2247
2248bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2249 if (occlusionInfo.hasBlockingOcclusion) {
2250 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2251 occlusionInfo.obscuringUid);
2252 return false;
2253 }
2254 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2255 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2256 "%.2f, maximum allowed = %.2f)",
2257 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2258 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2259 return false;
2260 }
2261 return true;
2262}
2263
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002264bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2265 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002266 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002267 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002268 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002269 if (windowHandle == otherHandle) {
2270 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002271 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002272 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002273 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002274 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002275 return true;
2276 }
2277 }
2278 return false;
2279}
2280
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002281bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2282 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002283 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002284 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002285 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002286 if (windowHandle == otherHandle) {
2287 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002288 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002289 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002290 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002291 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002292 return true;
2293 }
2294 }
2295 return false;
2296}
2297
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002298std::string InputDispatcher::getApplicationWindowLabel(
Chris Yea209fde2020-07-22 13:54:51 -07002299 const std::shared_ptr<InputApplicationHandle>& applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002300 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002301 if (applicationHandle != nullptr) {
2302 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002303 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002304 } else {
2305 return applicationHandle->getName();
2306 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002307 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002308 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002309 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002310 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002311 }
2312}
2313
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002314void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002315 if (eventEntry.type == EventEntry::Type::FOCUS) {
2316 // Focus events are passed to apps, but do not represent user activity.
2317 return;
2318 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002319 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002320 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002321 if (focusedWindowHandle != nullptr) {
2322 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002323 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002324#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002325 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002326#endif
2327 return;
2328 }
2329 }
2330
2331 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002332 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002333 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002334 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2335 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002336 return;
2337 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002338
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002339 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002340 eventType = USER_ACTIVITY_EVENT_TOUCH;
2341 }
2342 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002343 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002344 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002345 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2346 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002347 return;
2348 }
2349 eventType = USER_ACTIVITY_EVENT_BUTTON;
2350 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002351 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002352 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002353 case EventEntry::Type::CONFIGURATION_CHANGED:
2354 case EventEntry::Type::DEVICE_RESET: {
2355 LOG_ALWAYS_FATAL("%s events are not user activity",
2356 EventEntry::typeToString(eventEntry.type));
2357 break;
2358 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002359 }
2360
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002361 std::unique_ptr<CommandEntry> commandEntry =
2362 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002363 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002364 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002365 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002366}
2367
2368void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002369 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002370 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002371 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002372 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002373 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002374 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002375 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002376 ATRACE_NAME(message.c_str());
2377 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002378#if DEBUG_DISPATCH_CYCLE
2379 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002380 "globalScaleFactor=%f, pointerIds=0x%x %s",
2381 connection->getInputChannelName().c_str(), inputTarget.flags,
2382 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2383 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002384#endif
2385
2386 // Skip this event if the connection status is not normal.
2387 // We don't want to enqueue additional outbound events if the connection is broken.
2388 if (connection->status != Connection::STATUS_NORMAL) {
2389#if DEBUG_DISPATCH_CYCLE
2390 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002391 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002392#endif
2393 return;
2394 }
2395
2396 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002397 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2398 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2399 "Entry type %s should not have FLAG_SPLIT",
2400 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002401
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002402 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002403 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002404 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002405 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002406 if (!splitMotionEntry) {
2407 return; // split event was dropped
2408 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002409 if (DEBUG_FOCUS) {
2410 ALOGD("channel '%s' ~ Split motion event.",
2411 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002412 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002413 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002414 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2415 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002416 return;
2417 }
2418 }
2419
2420 // Not splitting. Enqueue dispatch entries for the event as is.
2421 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2422}
2423
2424void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002425 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002426 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002427 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002428 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002429 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002430 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002431 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002432 ATRACE_NAME(message.c_str());
2433 }
2434
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002435 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002436
2437 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002438 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002439 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002440 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002441 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002442 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002443 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002444 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002445 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002446 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002447 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002448 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002449 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002450
2451 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002452 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002453 startDispatchCycleLocked(currentTime, connection);
2454 }
2455}
2456
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002457void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002458 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002459 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002460 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002461 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002462 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2463 connection->getInputChannelName().c_str(),
2464 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002465 ATRACE_NAME(message.c_str());
2466 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002467 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002468 if (!(inputTargetFlags & dispatchMode)) {
2469 return;
2470 }
2471 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2472
2473 // This is a new event.
2474 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002475 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002476 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002477
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002478 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2479 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002480 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002481 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002482 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002483 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002484 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002485 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002486 dispatchEntry->resolvedAction = keyEntry.action;
2487 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002488
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002489 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2490 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002491#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002492 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2493 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002494#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002495 return; // skip the inconsistent event
2496 }
2497 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002498 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002499
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002500 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002501 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002502 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2503 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2504 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2505 static_cast<int32_t>(IdGenerator::Source::OTHER);
2506 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002507 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2508 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2509 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2510 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2511 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2512 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2513 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2514 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2515 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2516 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2517 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002518 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002519 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002520 }
2521 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002522 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2523 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002524#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002525 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2526 "event",
2527 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002528#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002529 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2530 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002531
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002532 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002533 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2534 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2535 }
2536 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2537 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2538 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002539
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002540 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2541 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002542#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002543 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2544 "event",
2545 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002546#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002547 return; // skip the inconsistent event
2548 }
2549
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002550 dispatchEntry->resolvedEventId =
2551 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2552 ? mIdGenerator.nextId()
2553 : motionEntry.id;
2554 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2555 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2556 ") to MotionEvent(id=0x%" PRIx32 ").",
2557 motionEntry.id, dispatchEntry->resolvedEventId);
2558 ATRACE_NAME(message.c_str());
2559 }
2560
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002561 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002562 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002563
2564 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002565 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002566 case EventEntry::Type::FOCUS: {
2567 break;
2568 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002569 case EventEntry::Type::CONFIGURATION_CHANGED:
2570 case EventEntry::Type::DEVICE_RESET: {
2571 LOG_ALWAYS_FATAL("%s events should not go to apps",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002572 EventEntry::typeToString(newEntry.type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002573 break;
2574 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002575 }
2576
2577 // Remember that we are waiting for this dispatch to complete.
2578 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002579 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002580 }
2581
2582 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002583 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002584 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002585}
2586
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002587/**
2588 * This function is purely for debugging. It helps us understand where the user interaction
2589 * was taking place. For example, if user is touching launcher, we will see a log that user
2590 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2591 * We will see both launcher and wallpaper in that list.
2592 * Once the interaction with a particular set of connections starts, no new logs will be printed
2593 * until the set of interacted connections changes.
2594 *
2595 * The following items are skipped, to reduce the logspam:
2596 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2597 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2598 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2599 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2600 * Both of those ACTION_UP events would not be logged
2601 * Monitors (both gesture and global): any gesture monitors or global monitors receiving events
2602 * will not be logged. This is omitted to reduce the amount of data printed.
2603 * If you see <none>, it's likely that one of the gesture monitors pilfered the event, and therefore
2604 * gesture monitor is the only connection receiving the remainder of the gesture.
2605 */
2606void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2607 const std::vector<InputTarget>& targets) {
2608 // Skip ACTION_UP events, and all events other than keys and motions
2609 if (entry.type == EventEntry::Type::KEY) {
2610 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2611 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2612 return;
2613 }
2614 } else if (entry.type == EventEntry::Type::MOTION) {
2615 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2616 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2617 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2618 return;
2619 }
2620 } else {
2621 return; // Not a key or a motion
2622 }
2623
2624 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2625 std::vector<sp<Connection>> newConnections;
2626 for (const InputTarget& target : targets) {
2627 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2628 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2629 continue; // Skip windows that receive ACTION_OUTSIDE
2630 }
2631
2632 sp<IBinder> token = target.inputChannel->getConnectionToken();
2633 sp<Connection> connection = getConnectionLocked(token);
2634 if (connection == nullptr || connection->monitor) {
2635 continue; // We only need to keep track of the non-monitor connections.
2636 }
2637 newConnectionTokens.insert(std::move(token));
2638 newConnections.emplace_back(connection);
2639 }
2640 if (newConnectionTokens == mInteractionConnectionTokens) {
2641 return; // no change
2642 }
2643 mInteractionConnectionTokens = newConnectionTokens;
2644
2645 std::string windowList;
2646 for (const sp<Connection>& connection : newConnections) {
2647 windowList += connection->getWindowName() + ", ";
2648 }
2649 std::string message = "Interaction with windows: " + windowList;
2650 if (windowList.empty()) {
2651 message += "<none>";
2652 }
2653 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2654}
2655
chaviwfd6d3512019-03-25 13:23:49 -07002656void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002657 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002658 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002659 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2660 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002661 return;
2662 }
2663
Vishnu Nairad321cd2020-08-20 16:40:21 -07002664 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
2665 if (focusedToken == token) {
2666 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002667 return;
2668 }
2669
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002670 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2671 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002672 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002673 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002674}
2675
2676void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002677 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002678 if (ATRACE_ENABLED()) {
2679 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002680 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002681 ATRACE_NAME(message.c_str());
2682 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002683#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002684 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002685#endif
2686
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002687 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2688 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002689 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002690 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002691 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002692 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002693
2694 // Publish the event.
2695 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002696 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
2697 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002698 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002699 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2700 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002701
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002702 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002703 status = connection->inputPublisher
2704 .publishKeyEvent(dispatchEntry->seq,
2705 dispatchEntry->resolvedEventId, keyEntry.deviceId,
2706 keyEntry.source, keyEntry.displayId,
2707 std::move(hmac), dispatchEntry->resolvedAction,
2708 dispatchEntry->resolvedFlags, keyEntry.keyCode,
2709 keyEntry.scanCode, keyEntry.metaState,
2710 keyEntry.repeatCount, keyEntry.downTime,
2711 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002712 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002713 }
2714
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002715 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002716 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002717
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002718 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002719 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002720
chaviw82357092020-01-28 13:13:06 -08002721 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002722 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002723 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2724 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002725 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002726 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
2727 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002728 // Don't apply window scale here since we don't want scale to affect raw
2729 // coordinates. The scale will be sent back to the client and applied
2730 // later when requesting relative coordinates.
2731 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2732 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002733 }
2734 usingCoords = scaledCoords;
2735 }
2736 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002737 // We don't want the dispatch target to know.
2738 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002739 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002740 scaledCoords[i].clear();
2741 }
2742 usingCoords = scaledCoords;
2743 }
2744 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002745
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002746 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002747
2748 // Publish the motion event.
2749 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002750 .publishMotionEvent(dispatchEntry->seq,
2751 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002752 motionEntry.deviceId, motionEntry.source,
2753 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002754 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002755 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002756 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002757 motionEntry.edgeFlags, motionEntry.metaState,
2758 motionEntry.buttonState,
2759 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07002760 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002761 motionEntry.xPrecision, motionEntry.yPrecision,
2762 motionEntry.xCursorPosition,
2763 motionEntry.yCursorPosition,
2764 motionEntry.downTime, motionEntry.eventTime,
2765 motionEntry.pointerCount,
2766 motionEntry.pointerProperties, usingCoords);
2767 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002768 break;
2769 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002770 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002771 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002772 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002773 focusEntry.id,
2774 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002775 mInTouchMode);
2776 break;
2777 }
2778
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002779 case EventEntry::Type::CONFIGURATION_CHANGED:
2780 case EventEntry::Type::DEVICE_RESET: {
2781 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002782 EventEntry::typeToString(eventEntry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002783 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002784 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002785 }
2786
2787 // Check the result.
2788 if (status) {
2789 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002790 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002791 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002792 "This is unexpected because the wait queue is empty, so the pipe "
2793 "should be empty and we shouldn't have any problems writing an "
2794 "event to it, status=%d",
2795 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002796 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2797 } else {
2798 // Pipe is full and we are waiting for the app to finish process some events
2799 // before sending more events to it.
2800#if DEBUG_DISPATCH_CYCLE
2801 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002802 "waiting for the application to catch up",
2803 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002804#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08002805 }
2806 } else {
2807 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002808 "status=%d",
2809 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002810 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2811 }
2812 return;
2813 }
2814
2815 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002816 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2817 connection->outboundQueue.end(),
2818 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002819 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002820 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002821 if (connection->responsive) {
2822 mAnrTracker.insert(dispatchEntry->timeoutTime,
2823 connection->inputChannel->getConnectionToken());
2824 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002825 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002826 }
2827}
2828
chaviw09c8d2d2020-08-24 15:48:26 -07002829std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
2830 size_t size;
2831 switch (event.type) {
2832 case VerifiedInputEvent::Type::KEY: {
2833 size = sizeof(VerifiedKeyEvent);
2834 break;
2835 }
2836 case VerifiedInputEvent::Type::MOTION: {
2837 size = sizeof(VerifiedMotionEvent);
2838 break;
2839 }
2840 }
2841 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
2842 return mHmacKeyManager.sign(start, size);
2843}
2844
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002845const std::array<uint8_t, 32> InputDispatcher::getSignature(
2846 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
2847 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
2848 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
2849 // Only sign events up and down events as the purely move events
2850 // are tied to their up/down counterparts so signing would be redundant.
2851 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
2852 verifiedEvent.actionMasked = actionMasked;
2853 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07002854 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002855 }
2856 return INVALID_HMAC;
2857}
2858
2859const std::array<uint8_t, 32> InputDispatcher::getSignature(
2860 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
2861 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
2862 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
2863 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07002864 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002865}
2866
Michael Wrightd02c5b62014-02-10 15:10:22 -08002867void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002868 const sp<Connection>& connection, uint32_t seq,
2869 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002870#if DEBUG_DISPATCH_CYCLE
2871 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002872 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002873#endif
2874
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002875 if (connection->status == Connection::STATUS_BROKEN ||
2876 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002877 return;
2878 }
2879
2880 // Notify other system components and prepare to start the next dispatch cycle.
2881 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2882}
2883
2884void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002885 const sp<Connection>& connection,
2886 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002887#if DEBUG_DISPATCH_CYCLE
2888 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002889 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002890#endif
2891
2892 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002893 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002894 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002895 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002896 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002897
2898 // The connection appears to be unrecoverably broken.
2899 // Ignore already broken or zombie connections.
2900 if (connection->status == Connection::STATUS_NORMAL) {
2901 connection->status = Connection::STATUS_BROKEN;
2902
2903 if (notify) {
2904 // Notify other system components.
2905 onDispatchCycleBrokenLocked(currentTime, connection);
2906 }
2907 }
2908}
2909
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002910void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2911 while (!queue.empty()) {
2912 DispatchEntry* dispatchEntry = queue.front();
2913 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002914 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002915 }
2916}
2917
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002918void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002919 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002920 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002921 }
2922 delete dispatchEntry;
2923}
2924
2925int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2926 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2927
2928 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002929 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002930
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002931 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002932 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002933 "fd=%d, events=0x%x",
2934 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002935 return 0; // remove the callback
2936 }
2937
2938 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002939 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002940 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2941 if (!(events & ALOOPER_EVENT_INPUT)) {
2942 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002943 "events=0x%x",
2944 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002945 return 1;
2946 }
2947
2948 nsecs_t currentTime = now();
2949 bool gotOne = false;
2950 status_t status;
2951 for (;;) {
2952 uint32_t seq;
2953 bool handled;
2954 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2955 if (status) {
2956 break;
2957 }
2958 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2959 gotOne = true;
2960 }
2961 if (gotOne) {
2962 d->runCommandsLockedInterruptible();
2963 if (status == WOULD_BLOCK) {
2964 return 1;
2965 }
2966 }
2967
2968 notify = status != DEAD_OBJECT || !connection->monitor;
2969 if (notify) {
2970 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002971 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002972 }
2973 } else {
2974 // Monitor channels are never explicitly unregistered.
2975 // We do it automatically when the remote endpoint is closed so don't warn
2976 // about them.
arthurhungd352cb32020-04-28 17:09:28 +08002977 const bool stillHaveWindowHandle =
2978 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
2979 nullptr;
2980 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002981 if (notify) {
2982 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002983 "events=0x%x",
2984 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002985 }
2986 }
2987
Garfield Tan15601662020-09-22 15:32:38 -07002988 // Remove the channel.
2989 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002990 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002991 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08002992}
2993
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002994void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002995 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002996 for (const auto& pair : mConnectionsByFd) {
2997 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002998 }
2999}
3000
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003001void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003002 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003003 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3004 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3005}
3006
3007void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3008 const CancelationOptions& options,
3009 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3010 for (const auto& it : monitorsByDisplay) {
3011 const std::vector<Monitor>& monitors = it.second;
3012 for (const Monitor& monitor : monitors) {
3013 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003014 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003015 }
3016}
3017
Michael Wrightd02c5b62014-02-10 15:10:22 -08003018void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003019 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003020 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003021 if (connection == nullptr) {
3022 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003023 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003024
3025 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003026}
3027
3028void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3029 const sp<Connection>& connection, const CancelationOptions& options) {
3030 if (connection->status == Connection::STATUS_BROKEN) {
3031 return;
3032 }
3033
3034 nsecs_t currentTime = now();
3035
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003036 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003037 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003038
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003039 if (cancelationEvents.empty()) {
3040 return;
3041 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003042#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003043 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3044 "with reality: %s, mode=%d.",
3045 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3046 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003047#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003048
3049 InputTarget target;
3050 sp<InputWindowHandle> windowHandle =
3051 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3052 if (windowHandle != nullptr) {
3053 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003054 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003055 target.globalScaleFactor = windowInfo->globalScaleFactor;
3056 }
3057 target.inputChannel = connection->inputChannel;
3058 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3059
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003060 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003061 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003062 switch (cancelationEventEntry->type) {
3063 case EventEntry::Type::KEY: {
3064 logOutboundKeyDetails("cancel - ",
3065 static_cast<const KeyEntry&>(*cancelationEventEntry));
3066 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003067 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003068 case EventEntry::Type::MOTION: {
3069 logOutboundMotionDetails("cancel - ",
3070 static_cast<const MotionEntry&>(*cancelationEventEntry));
3071 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003072 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003073 case EventEntry::Type::FOCUS: {
3074 LOG_ALWAYS_FATAL("Canceling focus events is not supported");
3075 break;
3076 }
3077 case EventEntry::Type::CONFIGURATION_CHANGED:
3078 case EventEntry::Type::DEVICE_RESET: {
3079 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3080 EventEntry::typeToString(cancelationEventEntry->type));
3081 break;
3082 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003083 }
3084
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003085 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3086 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003087 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003088
3089 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003090}
3091
Svet Ganov5d3bc372020-01-26 23:11:07 -08003092void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3093 const sp<Connection>& connection) {
3094 if (connection->status == Connection::STATUS_BROKEN) {
3095 return;
3096 }
3097
3098 nsecs_t currentTime = now();
3099
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003100 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003101 connection->inputState.synthesizePointerDownEvents(currentTime);
3102
3103 if (downEvents.empty()) {
3104 return;
3105 }
3106
3107#if DEBUG_OUTBOUND_EVENT_DETAILS
3108 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3109 connection->getInputChannelName().c_str(), downEvents.size());
3110#endif
3111
3112 InputTarget target;
3113 sp<InputWindowHandle> windowHandle =
3114 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3115 if (windowHandle != nullptr) {
3116 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003117 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003118 target.globalScaleFactor = windowInfo->globalScaleFactor;
3119 }
3120 target.inputChannel = connection->inputChannel;
3121 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3122
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003123 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003124 switch (downEventEntry->type) {
3125 case EventEntry::Type::MOTION: {
3126 logOutboundMotionDetails("down - ",
3127 static_cast<const MotionEntry&>(*downEventEntry));
3128 break;
3129 }
3130
3131 case EventEntry::Type::KEY:
3132 case EventEntry::Type::FOCUS:
3133 case EventEntry::Type::CONFIGURATION_CHANGED:
3134 case EventEntry::Type::DEVICE_RESET: {
3135 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3136 EventEntry::typeToString(downEventEntry->type));
3137 break;
3138 }
3139 }
3140
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003141 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3142 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003143 }
3144
3145 startDispatchCycleLocked(currentTime, connection);
3146}
3147
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003148std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3149 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003150 ALOG_ASSERT(pointerIds.value != 0);
3151
3152 uint32_t splitPointerIndexMap[MAX_POINTERS];
3153 PointerProperties splitPointerProperties[MAX_POINTERS];
3154 PointerCoords splitPointerCoords[MAX_POINTERS];
3155
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003156 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003157 uint32_t splitPointerCount = 0;
3158
3159 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003160 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003161 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003162 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003163 uint32_t pointerId = uint32_t(pointerProperties.id);
3164 if (pointerIds.hasBit(pointerId)) {
3165 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3166 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3167 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003168 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003169 splitPointerCount += 1;
3170 }
3171 }
3172
3173 if (splitPointerCount != pointerIds.count()) {
3174 // This is bad. We are missing some of the pointers that we expected to deliver.
3175 // Most likely this indicates that we received an ACTION_MOVE events that has
3176 // different pointer ids than we expected based on the previous ACTION_DOWN
3177 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3178 // in this way.
3179 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003180 "we expected there to be %d pointers. This probably means we received "
3181 "a broken sequence of pointer ids from the input device.",
3182 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003183 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003184 }
3185
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003186 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003187 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003188 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3189 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003190 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3191 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003192 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003193 uint32_t pointerId = uint32_t(pointerProperties.id);
3194 if (pointerIds.hasBit(pointerId)) {
3195 if (pointerIds.count() == 1) {
3196 // The first/last pointer went down/up.
3197 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003198 ? AMOTION_EVENT_ACTION_DOWN
3199 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003200 } else {
3201 // A secondary pointer went down/up.
3202 uint32_t splitPointerIndex = 0;
3203 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3204 splitPointerIndex += 1;
3205 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003206 action = maskedAction |
3207 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003208 }
3209 } else {
3210 // An unrelated pointer changed.
3211 action = AMOTION_EVENT_ACTION_MOVE;
3212 }
3213 }
3214
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003215 int32_t newId = mIdGenerator.nextId();
3216 if (ATRACE_ENABLED()) {
3217 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3218 ") to MotionEvent(id=0x%" PRIx32 ").",
3219 originalMotionEntry.id, newId);
3220 ATRACE_NAME(message.c_str());
3221 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003222 std::unique_ptr<MotionEntry> splitMotionEntry =
3223 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3224 originalMotionEntry.deviceId, originalMotionEntry.source,
3225 originalMotionEntry.displayId,
3226 originalMotionEntry.policyFlags, action,
3227 originalMotionEntry.actionButton,
3228 originalMotionEntry.flags, originalMotionEntry.metaState,
3229 originalMotionEntry.buttonState,
3230 originalMotionEntry.classification,
3231 originalMotionEntry.edgeFlags,
3232 originalMotionEntry.xPrecision,
3233 originalMotionEntry.yPrecision,
3234 originalMotionEntry.xCursorPosition,
3235 originalMotionEntry.yCursorPosition,
3236 originalMotionEntry.downTime, splitPointerCount,
3237 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003238
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003239 if (originalMotionEntry.injectionState) {
3240 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003241 splitMotionEntry->injectionState->refCount += 1;
3242 }
3243
3244 return splitMotionEntry;
3245}
3246
3247void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3248#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003249 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003250#endif
3251
3252 bool needWake;
3253 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003254 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003255
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003256 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3257 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3258 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003259 } // release lock
3260
3261 if (needWake) {
3262 mLooper->wake();
3263 }
3264}
3265
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003266/**
3267 * If one of the meta shortcuts is detected, process them here:
3268 * Meta + Backspace -> generate BACK
3269 * Meta + Enter -> generate HOME
3270 * This will potentially overwrite keyCode and metaState.
3271 */
3272void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003273 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003274 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3275 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3276 if (keyCode == AKEYCODE_DEL) {
3277 newKeyCode = AKEYCODE_BACK;
3278 } else if (keyCode == AKEYCODE_ENTER) {
3279 newKeyCode = AKEYCODE_HOME;
3280 }
3281 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003282 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003283 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003284 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003285 keyCode = newKeyCode;
3286 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3287 }
3288 } else if (action == AKEY_EVENT_ACTION_UP) {
3289 // In order to maintain a consistent stream of up and down events, check to see if the key
3290 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3291 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003292 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003293 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003294 auto replacementIt = mReplacedKeys.find(replacement);
3295 if (replacementIt != mReplacedKeys.end()) {
3296 keyCode = replacementIt->second;
3297 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003298 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3299 }
3300 }
3301}
3302
Michael Wrightd02c5b62014-02-10 15:10:22 -08003303void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3304#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003305 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3306 "policyFlags=0x%x, action=0x%x, "
3307 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3308 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3309 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3310 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003311#endif
3312 if (!validateKeyEvent(args->action)) {
3313 return;
3314 }
3315
3316 uint32_t policyFlags = args->policyFlags;
3317 int32_t flags = args->flags;
3318 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003319 // InputDispatcher tracks and generates key repeats on behalf of
3320 // whatever notifies it, so repeatCount should always be set to 0
3321 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003322 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3323 policyFlags |= POLICY_FLAG_VIRTUAL;
3324 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3325 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003326 if (policyFlags & POLICY_FLAG_FUNCTION) {
3327 metaState |= AMETA_FUNCTION_ON;
3328 }
3329
3330 policyFlags |= POLICY_FLAG_TRUSTED;
3331
Michael Wright78f24442014-08-06 15:55:28 -07003332 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003333 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003334
Michael Wrightd02c5b62014-02-10 15:10:22 -08003335 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003336 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003337 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3338 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003339
Michael Wright2b3c3302018-03-02 17:19:13 +00003340 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003341 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003342 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3343 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003344 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003345 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003346
Michael Wrightd02c5b62014-02-10 15:10:22 -08003347 bool needWake;
3348 { // acquire lock
3349 mLock.lock();
3350
3351 if (shouldSendKeyToInputFilterLocked(args)) {
3352 mLock.unlock();
3353
3354 policyFlags |= POLICY_FLAG_FILTERED;
3355 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3356 return; // event was consumed by the filter
3357 }
3358
3359 mLock.lock();
3360 }
3361
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003362 std::unique_ptr<KeyEntry> newEntry =
3363 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3364 args->displayId, policyFlags, args->action, flags,
3365 keyCode, args->scanCode, metaState, repeatCount,
3366 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003367
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003368 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003369 mLock.unlock();
3370 } // release lock
3371
3372 if (needWake) {
3373 mLooper->wake();
3374 }
3375}
3376
3377bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3378 return mInputFilterEnabled;
3379}
3380
3381void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3382#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003383 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3384 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003385 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3386 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003387 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003388 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3389 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3390 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3391 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003392 for (uint32_t i = 0; i < args->pointerCount; i++) {
3393 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003394 "x=%f, y=%f, pressure=%f, size=%f, "
3395 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3396 "orientation=%f",
3397 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3398 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3399 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3400 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3401 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3402 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3403 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3404 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3405 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3406 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003407 }
3408#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003409 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3410 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003411 return;
3412 }
3413
3414 uint32_t policyFlags = args->policyFlags;
3415 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003416
3417 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003418 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003419 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3420 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003421 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003422 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003423
3424 bool needWake;
3425 { // acquire lock
3426 mLock.lock();
3427
3428 if (shouldSendMotionToInputFilterLocked(args)) {
3429 mLock.unlock();
3430
3431 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003432 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003433 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3434 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003435 args->metaState, args->buttonState, args->classification, transform,
3436 args->xPrecision, args->yPrecision, args->xCursorPosition,
3437 args->yCursorPosition, args->downTime, args->eventTime,
3438 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003439
3440 policyFlags |= POLICY_FLAG_FILTERED;
3441 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3442 return; // event was consumed by the filter
3443 }
3444
3445 mLock.lock();
3446 }
3447
3448 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003449 std::unique_ptr<MotionEntry> newEntry =
3450 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3451 args->source, args->displayId, policyFlags,
3452 args->action, args->actionButton, args->flags,
3453 args->metaState, args->buttonState,
3454 args->classification, args->edgeFlags,
3455 args->xPrecision, args->yPrecision,
3456 args->xCursorPosition, args->yCursorPosition,
3457 args->downTime, args->pointerCount,
3458 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003459
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003460 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003461 mLock.unlock();
3462 } // release lock
3463
3464 if (needWake) {
3465 mLooper->wake();
3466 }
3467}
3468
3469bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003470 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003471}
3472
3473void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3474#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003475 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003476 "switchMask=0x%08x",
3477 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003478#endif
3479
3480 uint32_t policyFlags = args->policyFlags;
3481 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003482 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003483}
3484
3485void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3486#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003487 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3488 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003489#endif
3490
3491 bool needWake;
3492 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003493 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003494
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003495 std::unique_ptr<DeviceResetEntry> newEntry =
3496 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3497 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003498 } // release lock
3499
3500 if (needWake) {
3501 mLooper->wake();
3502 }
3503}
3504
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003505InputEventInjectionResult InputDispatcher::injectInputEvent(
3506 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3507 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003508#if DEBUG_INBOUND_EVENT_DETAILS
3509 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003510 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3511 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003512#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003513 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003514
3515 policyFlags |= POLICY_FLAG_INJECTED;
3516 if (hasInjectionPermission(injectorPid, injectorUid)) {
3517 policyFlags |= POLICY_FLAG_TRUSTED;
3518 }
3519
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003520 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003521 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003522 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003523 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3524 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003525 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003526 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003527 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003528
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003529 int32_t flags = incomingKey.getFlags();
3530 int32_t keyCode = incomingKey.getKeyCode();
3531 int32_t metaState = incomingKey.getMetaState();
3532 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003533 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003534 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003535 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003536 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3537 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3538 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003539
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003540 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3541 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003542 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003543
3544 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3545 android::base::Timer t;
3546 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3547 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3548 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3549 std::to_string(t.duration().count()).c_str());
3550 }
3551 }
3552
3553 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003554 std::unique_ptr<KeyEntry> injectedEntry =
3555 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3556 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3557 incomingKey.getDisplayId(), policyFlags, action,
3558 flags, keyCode, incomingKey.getScanCode(), metaState,
3559 incomingKey.getRepeatCount(),
3560 incomingKey.getDownTime());
3561 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003562 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003563 }
3564
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003565 case AINPUT_EVENT_TYPE_MOTION: {
3566 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3567 int32_t action = motionEvent->getAction();
3568 size_t pointerCount = motionEvent->getPointerCount();
3569 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3570 int32_t actionButton = motionEvent->getActionButton();
3571 int32_t displayId = motionEvent->getDisplayId();
3572 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003573 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003574 }
3575
3576 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3577 nsecs_t eventTime = motionEvent->getEventTime();
3578 android::base::Timer t;
3579 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3580 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3581 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3582 std::to_string(t.duration().count()).c_str());
3583 }
3584 }
3585
3586 mLock.lock();
3587 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3588 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003589 std::unique_ptr<MotionEntry> injectedEntry =
3590 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3591 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3592 motionEvent->getDisplayId(), policyFlags, action,
3593 actionButton, motionEvent->getFlags(),
3594 motionEvent->getMetaState(),
3595 motionEvent->getButtonState(),
3596 motionEvent->getClassification(),
3597 motionEvent->getEdgeFlags(),
3598 motionEvent->getXPrecision(),
3599 motionEvent->getYPrecision(),
3600 motionEvent->getRawXCursorPosition(),
3601 motionEvent->getRawYCursorPosition(),
3602 motionEvent->getDownTime(),
3603 uint32_t(pointerCount), pointerProperties,
3604 samplePointerCoords, motionEvent->getXOffset(),
3605 motionEvent->getYOffset());
3606 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003607 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3608 sampleEventTimes += 1;
3609 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003610 std::unique_ptr<MotionEntry> nextInjectedEntry =
3611 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3612 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3613 motionEvent->getDisplayId(), policyFlags,
3614 action, actionButton, motionEvent->getFlags(),
3615 motionEvent->getMetaState(),
3616 motionEvent->getButtonState(),
3617 motionEvent->getClassification(),
3618 motionEvent->getEdgeFlags(),
3619 motionEvent->getXPrecision(),
3620 motionEvent->getYPrecision(),
3621 motionEvent->getRawXCursorPosition(),
3622 motionEvent->getRawYCursorPosition(),
3623 motionEvent->getDownTime(),
3624 uint32_t(pointerCount), pointerProperties,
3625 samplePointerCoords,
3626 motionEvent->getXOffset(),
3627 motionEvent->getYOffset());
3628 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003629 }
3630 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003631 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003632
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003633 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003634 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003635 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003636 }
3637
3638 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003639 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003640 injectionState->injectionIsAsync = true;
3641 }
3642
3643 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003644 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003645
3646 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003647 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003648 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003649 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003650 }
3651
3652 mLock.unlock();
3653
3654 if (needWake) {
3655 mLooper->wake();
3656 }
3657
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003658 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003659 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003660 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003661
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003662 if (syncMode == InputEventInjectionSync::NONE) {
3663 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003664 } else {
3665 for (;;) {
3666 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003667 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003668 break;
3669 }
3670
3671 nsecs_t remainingTimeout = endTime - now();
3672 if (remainingTimeout <= 0) {
3673#if DEBUG_INJECTION
3674 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003675 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003676#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003677 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003678 break;
3679 }
3680
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003681 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003682 }
3683
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003684 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3685 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003686 while (injectionState->pendingForegroundDispatches != 0) {
3687#if DEBUG_INJECTION
3688 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003689 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003690#endif
3691 nsecs_t remainingTimeout = endTime - now();
3692 if (remainingTimeout <= 0) {
3693#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003694 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3695 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003696#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003697 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003698 break;
3699 }
3700
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003701 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003702 }
3703 }
3704 }
3705
3706 injectionState->release();
3707 } // release lock
3708
3709#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003710 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003711 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003712#endif
3713
3714 return injectionResult;
3715}
3716
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003717std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05003718 std::array<uint8_t, 32> calculatedHmac;
3719 std::unique_ptr<VerifiedInputEvent> result;
3720 switch (event.getType()) {
3721 case AINPUT_EVENT_TYPE_KEY: {
3722 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
3723 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
3724 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003725 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05003726 break;
3727 }
3728 case AINPUT_EVENT_TYPE_MOTION: {
3729 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
3730 VerifiedMotionEvent verifiedMotionEvent =
3731 verifiedMotionEventFromMotionEvent(motionEvent);
3732 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003733 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05003734 break;
3735 }
3736 default: {
3737 ALOGE("Cannot verify events of type %" PRId32, event.getType());
3738 return nullptr;
3739 }
3740 }
3741 if (calculatedHmac == INVALID_HMAC) {
3742 return nullptr;
3743 }
3744 if (calculatedHmac != event.getHmac()) {
3745 return nullptr;
3746 }
3747 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003748}
3749
Michael Wrightd02c5b62014-02-10 15:10:22 -08003750bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003751 return injectorUid == 0 ||
3752 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003753}
3754
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003755void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003756 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003757 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003758 if (injectionState) {
3759#if DEBUG_INJECTION
3760 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003761 "injectorPid=%d, injectorUid=%d",
3762 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003763#endif
3764
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003765 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003766 // Log the outcome since the injector did not wait for the injection result.
3767 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003768 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003769 ALOGV("Asynchronous input event injection succeeded.");
3770 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003771 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003772 ALOGW("Asynchronous input event injection failed.");
3773 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003774 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003775 ALOGW("Asynchronous input event injection permission denied.");
3776 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003777 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003778 ALOGW("Asynchronous input event injection timed out.");
3779 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003780 case InputEventInjectionResult::PENDING:
3781 ALOGE("Setting result to 'PENDING' for asynchronous injection");
3782 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003783 }
3784 }
3785
3786 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003787 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003788 }
3789}
3790
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003791void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
3792 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003793 if (injectionState) {
3794 injectionState->pendingForegroundDispatches += 1;
3795 }
3796}
3797
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003798void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
3799 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003800 if (injectionState) {
3801 injectionState->pendingForegroundDispatches -= 1;
3802
3803 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003804 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003805 }
3806 }
3807}
3808
Vishnu Nairad321cd2020-08-20 16:40:21 -07003809const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003810 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003811 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
3812 auto it = mWindowHandlesByDisplay.find(displayId);
3813 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08003814}
3815
Michael Wrightd02c5b62014-02-10 15:10:22 -08003816sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003817 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08003818 if (windowHandleToken == nullptr) {
3819 return nullptr;
3820 }
3821
Arthur Hungb92218b2018-08-14 12:00:21 +08003822 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003823 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003824 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003825 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003826 return windowHandle;
3827 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003828 }
3829 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003830 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003831}
3832
Vishnu Nairad321cd2020-08-20 16:40:21 -07003833sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
3834 int displayId) const {
3835 if (windowHandleToken == nullptr) {
3836 return nullptr;
3837 }
3838
3839 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3840 if (windowHandle->getToken() == windowHandleToken) {
3841 return windowHandle;
3842 }
3843 }
3844 return nullptr;
3845}
3846
3847sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
3848 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
3849 return getWindowHandleLocked(focusedToken, displayId);
3850}
3851
Mady Mellor017bcd12020-06-23 19:12:00 +00003852bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
3853 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003854 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00003855 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08003856 if (handle->getId() == windowHandle->getId() &&
3857 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00003858 if (windowHandle->getInfo()->displayId != it.first) {
3859 ALOGE("Found window %s in display %" PRId32
3860 ", but it should belong to display %" PRId32,
3861 windowHandle->getName().c_str(), it.first,
3862 windowHandle->getInfo()->displayId);
3863 }
3864 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08003865 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003866 }
3867 }
3868 return false;
3869}
3870
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05003871bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
3872 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
3873 const bool noInputChannel =
3874 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3875 if (connection != nullptr && noInputChannel) {
3876 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
3877 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
3878 return false;
3879 }
3880
3881 if (connection == nullptr) {
3882 if (!noInputChannel) {
3883 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
3884 }
3885 return false;
3886 }
3887 if (!connection->responsive) {
3888 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
3889 return false;
3890 }
3891 return true;
3892}
3893
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003894std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
3895 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07003896 size_t count = mInputChannelsByToken.count(token);
3897 if (count == 0) {
3898 return nullptr;
3899 }
3900 return mInputChannelsByToken.at(token);
3901}
3902
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003903void InputDispatcher::updateWindowHandlesForDisplayLocked(
3904 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3905 if (inputWindowHandles.empty()) {
3906 // Remove all handles on a display if there are no windows left.
3907 mWindowHandlesByDisplay.erase(displayId);
3908 return;
3909 }
3910
3911 // Since we compare the pointer of input window handles across window updates, we need
3912 // to make sure the handle object for the same window stays unchanged across updates.
3913 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003914 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003915 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003916 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003917 }
3918
3919 std::vector<sp<InputWindowHandle>> newHandles;
3920 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3921 if (!handle->updateInfo()) {
3922 // handle no longer valid
3923 continue;
3924 }
3925
3926 const InputWindowInfo* info = handle->getInfo();
3927 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3928 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3929 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01003930 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3931 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
3932 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003933 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003934 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003935 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07003936 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003937 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003938 }
3939
3940 if (info->displayId != displayId) {
3941 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3942 handle->getName().c_str(), displayId, info->displayId);
3943 continue;
3944 }
3945
Robert Carredd13602020-04-13 17:24:34 -07003946 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
3947 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07003948 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003949 oldHandle->updateFrom(handle);
3950 newHandles.push_back(oldHandle);
3951 } else {
3952 newHandles.push_back(handle);
3953 }
3954 }
3955
3956 // Insert or replace
3957 mWindowHandlesByDisplay[displayId] = newHandles;
3958}
3959
Arthur Hung72d8dc32020-03-28 00:48:39 +00003960void InputDispatcher::setInputWindows(
3961 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
3962 { // acquire lock
3963 std::scoped_lock _l(mLock);
3964 for (auto const& i : handlesPerDisplay) {
3965 setInputWindowsLocked(i.second, i.first);
3966 }
3967 }
3968 // Wake up poll loop since it may need to make new input dispatching choices.
3969 mLooper->wake();
3970}
3971
Arthur Hungb92218b2018-08-14 12:00:21 +08003972/**
3973 * Called from InputManagerService, update window handle list by displayId that can receive input.
3974 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3975 * If set an empty list, remove all handles from the specific display.
3976 * For focused handle, check if need to change and send a cancel event to previous one.
3977 * For removed handle, check if need to send a cancel event if already in touch.
3978 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00003979void InputDispatcher::setInputWindowsLocked(
3980 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003981 if (DEBUG_FOCUS) {
3982 std::string windowList;
3983 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
3984 windowList += iwh->getName() + " ";
3985 }
3986 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
3987 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003988
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05003989 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
3990 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
3991 const bool noInputWindow =
3992 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3993 if (noInputWindow && window->getToken() != nullptr) {
3994 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
3995 window->getName().c_str());
3996 window->releaseChannel();
3997 }
3998 }
3999
Arthur Hung72d8dc32020-03-28 00:48:39 +00004000 // Copy old handles for release if they are no longer present.
4001 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004002
Arthur Hung72d8dc32020-03-28 00:48:39 +00004003 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004004
Vishnu Nair958da932020-08-21 17:12:37 -07004005 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4006 if (mLastHoverWindowHandle &&
4007 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4008 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004009 mLastHoverWindowHandle = nullptr;
4010 }
4011
Vishnu Nair958da932020-08-21 17:12:37 -07004012 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4013 if (focusedToken) {
4014 FocusResult result = checkTokenFocusableLocked(focusedToken, displayId);
4015 if (result != FocusResult::OK) {
4016 onFocusChangedLocked(focusedToken, nullptr, displayId, typeToString(result));
4017 }
4018 }
4019
4020 std::optional<FocusRequest> focusRequest =
4021 getOptionalValueByKey(mPendingFocusRequests, displayId);
4022 if (focusRequest) {
4023 // If the window from the pending request is now visible, provide it focus.
4024 FocusResult result = handleFocusRequestLocked(*focusRequest);
4025 if (result != FocusResult::NOT_VISIBLE) {
4026 // Drop the request if we were able to change the focus or we cannot change
4027 // it for another reason.
4028 mPendingFocusRequests.erase(displayId);
4029 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004030 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004031
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004032 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4033 mTouchStatesByDisplay.find(displayId);
4034 if (stateIt != mTouchStatesByDisplay.end()) {
4035 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004036 for (size_t i = 0; i < state.windows.size();) {
4037 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004038 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004039 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004040 ALOGD("Touched window was removed: %s in display %" PRId32,
4041 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004042 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004043 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004044 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4045 if (touchedInputChannel != nullptr) {
4046 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4047 "touched window was removed");
4048 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004049 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004050 state.windows.erase(state.windows.begin() + i);
4051 } else {
4052 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004053 }
4054 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004055 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004056
Arthur Hung72d8dc32020-03-28 00:48:39 +00004057 // Release information for windows that are no longer present.
4058 // This ensures that unused input channels are released promptly.
4059 // Otherwise, they might stick around until the window handle is destroyed
4060 // which might not happen until the next GC.
4061 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004062 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004063 if (DEBUG_FOCUS) {
4064 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004065 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004066 oldWindowHandle->releaseChannel();
Arthur Hung25e2af12020-03-26 12:58:37 +00004067 }
chaviw291d88a2019-02-14 10:33:58 -08004068 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004069}
4070
4071void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004072 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004073 if (DEBUG_FOCUS) {
4074 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4075 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4076 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004077 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004078 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004079
Chris Yea209fde2020-07-22 13:54:51 -07004080 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004081 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004082
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004083 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4084 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004085 }
4086
Chris Yea209fde2020-07-22 13:54:51 -07004087 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004088 if (inputApplicationHandle != nullptr) {
4089 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4090 } else {
4091 mFocusedApplicationHandlesByDisplay.erase(displayId);
4092 }
4093
4094 // No matter what the old focused application was, stop waiting on it because it is
4095 // no longer focused.
4096 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004097 } // release lock
4098
4099 // Wake up poll loop since it may need to make new input dispatching choices.
4100 mLooper->wake();
4101}
4102
Tiger Huang721e26f2018-07-24 22:26:19 +08004103/**
4104 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4105 * the display not specified.
4106 *
4107 * We track any unreleased events for each window. If a window loses the ability to receive the
4108 * released event, we will send a cancel event to it. So when the focused display is changed, we
4109 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4110 * display. The display-specified events won't be affected.
4111 */
4112void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004113 if (DEBUG_FOCUS) {
4114 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4115 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004116 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004117 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004118
4119 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004120 sp<IBinder> oldFocusedWindowToken =
4121 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4122 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004123 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004124 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004125 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004126 CancelationOptions
4127 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4128 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004129 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004130 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4131 }
4132 }
4133 mFocusedDisplayId = displayId;
4134
Chris Ye3c2d6f52020-08-09 10:39:48 -07004135 // Find new focused window and validate
Vishnu Nairad321cd2020-08-20 16:40:21 -07004136 sp<IBinder> newFocusedWindowToken =
4137 getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4138 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004139
Vishnu Nairad321cd2020-08-20 16:40:21 -07004140 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004141 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004142 if (!mFocusedWindowTokenByDisplay.empty()) {
4143 ALOGE("But another display has a focused window\n%s",
4144 dumpFocusedWindowsLocked().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004145 }
4146 }
4147 }
4148
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004149 if (DEBUG_FOCUS) {
4150 logDispatchStateLocked();
4151 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004152 } // release lock
4153
4154 // Wake up poll loop since it may need to make new input dispatching choices.
4155 mLooper->wake();
4156}
4157
Michael Wrightd02c5b62014-02-10 15:10:22 -08004158void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004159 if (DEBUG_FOCUS) {
4160 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4161 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004162
4163 bool changed;
4164 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004165 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004166
4167 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4168 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004169 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004170 }
4171
4172 if (mDispatchEnabled && !enabled) {
4173 resetAndDropEverythingLocked("dispatcher is being disabled");
4174 }
4175
4176 mDispatchEnabled = enabled;
4177 mDispatchFrozen = frozen;
4178 changed = true;
4179 } else {
4180 changed = false;
4181 }
4182
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004183 if (DEBUG_FOCUS) {
4184 logDispatchStateLocked();
4185 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004186 } // release lock
4187
4188 if (changed) {
4189 // Wake up poll loop since it may need to make new input dispatching choices.
4190 mLooper->wake();
4191 }
4192}
4193
4194void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004195 if (DEBUG_FOCUS) {
4196 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4197 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004198
4199 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004200 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004201
4202 if (mInputFilterEnabled == enabled) {
4203 return;
4204 }
4205
4206 mInputFilterEnabled = enabled;
4207 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4208 } // release lock
4209
4210 // Wake up poll loop since there might be work to do to drop everything.
4211 mLooper->wake();
4212}
4213
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004214void InputDispatcher::setInTouchMode(bool inTouchMode) {
4215 std::scoped_lock lock(mLock);
4216 mInTouchMode = inTouchMode;
4217}
4218
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004219void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4220 if (opacity < 0 || opacity > 1) {
4221 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4222 return;
4223 }
4224
4225 std::scoped_lock lock(mLock);
4226 mMaximumObscuringOpacityForTouch = opacity;
4227}
4228
4229void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4230 std::scoped_lock lock(mLock);
4231 mBlockUntrustedTouchesMode = mode;
4232}
4233
chaviwfbe5d9c2018-12-26 12:23:37 -08004234bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4235 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004236 if (DEBUG_FOCUS) {
4237 ALOGD("Trivial transfer to same window.");
4238 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004239 return true;
4240 }
4241
Michael Wrightd02c5b62014-02-10 15:10:22 -08004242 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004243 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004244
chaviwfbe5d9c2018-12-26 12:23:37 -08004245 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4246 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004247 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004248 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004249 return false;
4250 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004251 if (DEBUG_FOCUS) {
4252 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4253 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4254 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004255 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004256 if (DEBUG_FOCUS) {
4257 ALOGD("Cannot transfer focus because windows are on different displays.");
4258 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004259 return false;
4260 }
4261
4262 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004263 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4264 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004265 for (size_t i = 0; i < state.windows.size(); i++) {
4266 const TouchedWindow& touchedWindow = state.windows[i];
4267 if (touchedWindow.windowHandle == fromWindowHandle) {
4268 int32_t oldTargetFlags = touchedWindow.targetFlags;
4269 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004270
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004271 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004272
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004273 int32_t newTargetFlags = oldTargetFlags &
4274 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4275 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004276 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004277
Jeff Brownf086ddb2014-02-11 14:28:48 -08004278 found = true;
4279 goto Found;
4280 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004281 }
4282 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004283 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004284
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004285 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004286 if (DEBUG_FOCUS) {
4287 ALOGD("Focus transfer failed because from window did not have focus.");
4288 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004289 return false;
4290 }
4291
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004292 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4293 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004294 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004295 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004296 CancelationOptions
4297 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4298 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004299 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004300 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004301 }
4302
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004303 if (DEBUG_FOCUS) {
4304 logDispatchStateLocked();
4305 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004306 } // release lock
4307
4308 // Wake up poll loop since it may need to make new input dispatching choices.
4309 mLooper->wake();
4310 return true;
4311}
4312
4313void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004314 if (DEBUG_FOCUS) {
4315 ALOGD("Resetting and dropping all events (%s).", reason);
4316 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004317
4318 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4319 synthesizeCancelationEventsForAllConnectionsLocked(options);
4320
4321 resetKeyRepeatLocked();
4322 releasePendingEventLocked();
4323 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004324 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004325
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004326 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004327 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004328 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004329 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004330}
4331
4332void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004333 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004334 dumpDispatchStateLocked(dump);
4335
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004336 std::istringstream stream(dump);
4337 std::string line;
4338
4339 while (std::getline(stream, line, '\n')) {
4340 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004341 }
4342}
4343
Vishnu Nairad321cd2020-08-20 16:40:21 -07004344std::string InputDispatcher::dumpFocusedWindowsLocked() {
4345 if (mFocusedWindowTokenByDisplay.empty()) {
4346 return INDENT "FocusedWindows: <none>\n";
4347 }
4348
4349 std::string dump;
4350 dump += INDENT "FocusedWindows:\n";
4351 for (auto& it : mFocusedWindowTokenByDisplay) {
4352 const int32_t displayId = it.first;
4353 const sp<InputWindowHandle> windowHandle = getFocusedWindowHandleLocked(displayId);
4354 if (windowHandle) {
4355 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
4356 windowHandle->getName().c_str());
4357 } else {
4358 dump += StringPrintf(INDENT2 "displayId=%" PRId32
4359 " has focused token without a window'\n",
4360 displayId);
4361 }
4362 }
4363 return dump;
4364}
4365
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004366void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004367 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4368 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4369 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004370 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004371
Tiger Huang721e26f2018-07-24 22:26:19 +08004372 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4373 dump += StringPrintf(INDENT "FocusedApplications:\n");
4374 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4375 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004376 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004377 const std::chrono::duration timeout =
4378 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004379 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004380 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004381 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004382 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004383 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004384 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004385 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004386
Vishnu Nairad321cd2020-08-20 16:40:21 -07004387 dump += dumpFocusedWindowsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004388
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004389 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004390 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004391 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4392 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004393 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004394 state.displayId, toString(state.down), toString(state.split),
4395 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004396 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004397 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004398 for (size_t i = 0; i < state.windows.size(); i++) {
4399 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004400 dump += StringPrintf(INDENT4
4401 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4402 i, touchedWindow.windowHandle->getName().c_str(),
4403 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004404 }
4405 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004406 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004407 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004408 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004409 dump += INDENT3 "Portal windows:\n";
4410 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004411 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004412 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4413 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004414 }
4415 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004416 }
4417 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004418 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004419 }
4420
Arthur Hungb92218b2018-08-14 12:00:21 +08004421 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004422 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004423 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004424 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004425 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004426 dump += INDENT2 "Windows:\n";
4427 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004428 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004429 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004430
Arthur Hungb92218b2018-08-14 12:00:21 +08004431 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004432 "portalToDisplayId=%d, paused=%s, focusable=%s, "
4433 "hasWallpaper=%s, visible=%s, "
Michael Wright44753b12020-07-08 13:48:11 +01004434 "flags=%s, type=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004435 "frame=[%d,%d][%d,%d], globalScale=%f, "
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004436 "applicationInfo=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004437 "touchableRegion=",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004438 i, windowInfo->name.c_str(), windowInfo->displayId,
4439 windowInfo->portalToDisplayId,
4440 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004441 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004442 toString(windowInfo->hasWallpaper),
4443 toString(windowInfo->visible),
Michael Wright8759d672020-07-21 00:46:45 +01004444 windowInfo->flags.string().c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004445 static_cast<int32_t>(windowInfo->type),
4446 windowInfo->frameLeft, windowInfo->frameTop,
4447 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004448 windowInfo->globalScaleFactor,
4449 windowInfo->applicationInfo.name.c_str());
Arthur Hungb92218b2018-08-14 12:00:21 +08004450 dumpRegion(dump, windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004451 dump += StringPrintf(", inputFeatures=%s",
4452 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004453 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
4454 "ms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004455 windowInfo->ownerPid, windowInfo->ownerUid,
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05004456 millis(windowInfo->dispatchingTimeout));
chaviw85b44202020-07-24 11:46:21 -07004457 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004458 }
4459 } else {
4460 dump += INDENT2 "Windows: <none>\n";
4461 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004462 }
4463 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004464 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004465 }
4466
Michael Wright3dd60e22019-03-27 22:06:44 +00004467 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004468 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004469 const std::vector<Monitor>& monitors = it.second;
4470 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4471 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004472 }
4473 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004474 const std::vector<Monitor>& monitors = it.second;
4475 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4476 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004477 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004478 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004479 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004480 }
4481
4482 nsecs_t currentTime = now();
4483
4484 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004485 if (!mRecentQueue.empty()) {
4486 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004487 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004488 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004489 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004490 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004491 }
4492 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004493 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004494 }
4495
4496 // Dump event currently being dispatched.
4497 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004498 dump += INDENT "PendingEvent:\n";
4499 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004500 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004501 dump += StringPrintf(", age=%" PRId64 "ms\n",
4502 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004503 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004504 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004505 }
4506
4507 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004508 if (!mInboundQueue.empty()) {
4509 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004510 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004511 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004512 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004513 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004514 }
4515 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004516 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004517 }
4518
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004519 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004520 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004521 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4522 const KeyReplacement& replacement = pair.first;
4523 int32_t newKeyCode = pair.second;
4524 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004525 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004526 }
4527 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004528 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004529 }
4530
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004531 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004532 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004533 for (const auto& pair : mConnectionsByFd) {
4534 const sp<Connection>& connection = pair.second;
4535 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004536 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004537 pair.first, connection->getInputChannelName().c_str(),
4538 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004539 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004540
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004541 if (!connection->outboundQueue.empty()) {
4542 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4543 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004544 dump += dumpQueue(connection->outboundQueue, currentTime);
4545
Michael Wrightd02c5b62014-02-10 15:10:22 -08004546 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004547 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004548 }
4549
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004550 if (!connection->waitQueue.empty()) {
4551 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4552 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004553 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004554 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004555 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004556 }
4557 }
4558 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004559 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004560 }
4561
4562 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004563 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4564 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004565 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004566 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004567 }
4568
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004569 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004570 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4571 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4572 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004573}
4574
Michael Wright3dd60e22019-03-27 22:06:44 +00004575void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4576 const size_t numMonitors = monitors.size();
4577 for (size_t i = 0; i < numMonitors; i++) {
4578 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004579 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004580 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4581 dump += "\n";
4582 }
4583}
4584
Garfield Tan15601662020-09-22 15:32:38 -07004585base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4586 const std::string& name) {
4587#if DEBUG_CHANNEL_CREATION
4588 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004589#endif
4590
Garfield Tan15601662020-09-22 15:32:38 -07004591 std::shared_ptr<InputChannel> serverChannel;
4592 std::unique_ptr<InputChannel> clientChannel;
4593 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4594
4595 if (result) {
4596 return base::Error(result) << "Failed to open input channel pair with name " << name;
4597 }
4598
Michael Wrightd02c5b62014-02-10 15:10:22 -08004599 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004600 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004601 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004602
Garfield Tan15601662020-09-22 15:32:38 -07004603 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004604 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004605 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004606
Michael Wrightd02c5b62014-02-10 15:10:22 -08004607 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4608 } // release lock
4609
4610 // Wake the looper because some connections have changed.
4611 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004612 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004613}
4614
Garfield Tan15601662020-09-22 15:32:38 -07004615base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
4616 int32_t displayId, bool isGestureMonitor, const std::string& name) {
4617 std::shared_ptr<InputChannel> serverChannel;
4618 std::unique_ptr<InputChannel> clientChannel;
4619 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4620 if (result) {
4621 return base::Error(result) << "Failed to open input channel pair with name " << name;
4622 }
4623
Michael Wright3dd60e22019-03-27 22:06:44 +00004624 { // acquire lock
4625 std::scoped_lock _l(mLock);
4626
4627 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004628 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4629 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004630 }
4631
Garfield Tan15601662020-09-22 15:32:38 -07004632 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004633
Garfield Tan15601662020-09-22 15:32:38 -07004634 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004635 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004636 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004637
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004638 auto& monitorsByDisplay =
4639 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Garfield Tan15601662020-09-22 15:32:38 -07004640 monitorsByDisplay[displayId].emplace_back(serverChannel);
Michael Wright3dd60e22019-03-27 22:06:44 +00004641
4642 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004643 }
Garfield Tan15601662020-09-22 15:32:38 -07004644
Michael Wright3dd60e22019-03-27 22:06:44 +00004645 // Wake the looper because some connections have changed.
4646 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004647 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004648}
4649
Garfield Tan15601662020-09-22 15:32:38 -07004650status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004651 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004652 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004653
Garfield Tan15601662020-09-22 15:32:38 -07004654 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004655 if (status) {
4656 return status;
4657 }
4658 } // release lock
4659
4660 // Wake the poll loop because removing the connection may have changed the current
4661 // synchronization state.
4662 mLooper->wake();
4663 return OK;
4664}
4665
Garfield Tan15601662020-09-22 15:32:38 -07004666status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
4667 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004668 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004669 if (connection == nullptr) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004670 ALOGW("Attempted to unregister already unregistered input channel");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004671 return BAD_VALUE;
4672 }
4673
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004674 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004675 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07004676
Michael Wrightd02c5b62014-02-10 15:10:22 -08004677 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004678 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004679 }
4680
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004681 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004682
4683 nsecs_t currentTime = now();
4684 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4685
4686 connection->status = Connection::STATUS_ZOMBIE;
4687 return OK;
4688}
4689
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004690void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
4691 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
4692 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00004693}
4694
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004695void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004696 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00004697 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004698 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004699 std::vector<Monitor>& monitors = it->second;
4700 const size_t numMonitors = monitors.size();
4701 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004702 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004703 monitors.erase(monitors.begin() + i);
4704 break;
4705 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004706 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004707 if (monitors.empty()) {
4708 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004709 } else {
4710 ++it;
4711 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004712 }
4713}
4714
Michael Wright3dd60e22019-03-27 22:06:44 +00004715status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4716 { // acquire lock
4717 std::scoped_lock _l(mLock);
4718 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4719
4720 if (!foundDisplayId) {
4721 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4722 return BAD_VALUE;
4723 }
4724 int32_t displayId = foundDisplayId.value();
4725
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004726 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4727 mTouchStatesByDisplay.find(displayId);
4728 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004729 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4730 return BAD_VALUE;
4731 }
4732
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004733 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00004734 std::optional<int32_t> foundDeviceId;
4735 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004736 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004737 foundDeviceId = state.deviceId;
4738 }
4739 }
4740 if (!foundDeviceId || !state.down) {
4741 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004742 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004743 return BAD_VALUE;
4744 }
4745 int32_t deviceId = foundDeviceId.value();
4746
4747 // Send cancel events to all the input channels we're stealing from.
4748 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004749 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004750 options.deviceId = deviceId;
4751 options.displayId = displayId;
4752 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004753 std::shared_ptr<InputChannel> channel =
4754 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004755 if (channel != nullptr) {
4756 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4757 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004758 }
4759 // Then clear the current touch state so we stop dispatching to them as well.
4760 state.filterNonMonitors();
4761 }
4762 return OK;
4763}
4764
Michael Wright3dd60e22019-03-27 22:06:44 +00004765std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4766 const sp<IBinder>& token) {
4767 for (const auto& it : mGestureMonitorsByDisplay) {
4768 const std::vector<Monitor>& monitors = it.second;
4769 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004770 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004771 return it.first;
4772 }
4773 }
4774 }
4775 return std::nullopt;
4776}
4777
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004778sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004779 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004780 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004781 }
4782
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004783 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004784 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004785 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004786 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004787 }
4788 }
Robert Carr4e670e52018-08-15 13:26:12 -07004789
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004790 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004791}
4792
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004793void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004794 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004795 removeByValue(mConnectionsByFd, connection);
4796}
4797
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004798void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4799 const sp<Connection>& connection, uint32_t seq,
4800 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004801 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4802 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004803 commandEntry->connection = connection;
4804 commandEntry->eventTime = currentTime;
4805 commandEntry->seq = seq;
4806 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004807 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004808}
4809
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004810void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4811 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004812 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004813 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004814
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004815 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4816 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004817 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004818 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004819}
4820
Vishnu Nairad321cd2020-08-20 16:40:21 -07004821void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
4822 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004823 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4824 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004825 commandEntry->oldToken = oldToken;
4826 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004827 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004828}
4829
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004830void InputDispatcher::onAnrLocked(const Connection& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004831 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
4832 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004833 if (connection.waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004834 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004835 connection.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004836 return;
4837 }
4838 /**
4839 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
4840 * may not be the one that caused the timeout to occur. One possibility is that window timeout
4841 * has changed. This could cause newer entries to time out before the already dispatched
4842 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
4843 * processes the events linearly. So providing information about the oldest entry seems to be
4844 * most useful.
4845 */
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004846 DispatchEntry* oldestEntry = *connection.waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004847 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
4848 std::string reason =
4849 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004850 connection.inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004851 ns2ms(currentWait),
4852 oldestEntry->eventEntry->getDescription().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004853
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004854 updateLastAnrStateLocked(getWindowHandleLocked(connection.inputChannel->getConnectionToken()),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004855 reason);
4856
4857 std::unique_ptr<CommandEntry> commandEntry =
4858 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyAnrLockedInterruptible);
4859 commandEntry->inputApplicationHandle = nullptr;
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004860 commandEntry->inputChannel = connection.inputChannel;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004861 commandEntry->reason = std::move(reason);
4862 postCommandLocked(std::move(commandEntry));
4863}
4864
Chris Yea209fde2020-07-22 13:54:51 -07004865void InputDispatcher::onAnrLocked(const std::shared_ptr<InputApplicationHandle>& application) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004866 std::string reason = android::base::StringPrintf("%s does not have a focused window",
4867 application->getName().c_str());
4868
4869 updateLastAnrStateLocked(application, reason);
4870
4871 std::unique_ptr<CommandEntry> commandEntry =
4872 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyAnrLockedInterruptible);
4873 commandEntry->inputApplicationHandle = application;
4874 commandEntry->inputChannel = nullptr;
4875 commandEntry->reason = std::move(reason);
4876 postCommandLocked(std::move(commandEntry));
4877}
4878
4879void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
4880 const std::string& reason) {
4881 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
4882 updateLastAnrStateLocked(windowLabel, reason);
4883}
4884
Chris Yea209fde2020-07-22 13:54:51 -07004885void InputDispatcher::updateLastAnrStateLocked(
4886 const std::shared_ptr<InputApplicationHandle>& application, const std::string& reason) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004887 const std::string windowLabel = getApplicationWindowLabel(application, nullptr);
4888 updateLastAnrStateLocked(windowLabel, reason);
4889}
4890
4891void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
4892 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004893 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004894 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004895 struct tm tm;
4896 localtime_r(&t, &tm);
4897 char timestr[64];
4898 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07004899 mLastAnrState.clear();
4900 mLastAnrState += INDENT "ANR:\n";
4901 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004902 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
4903 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07004904 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004905}
4906
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004907void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004908 mLock.unlock();
4909
4910 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4911
4912 mLock.lock();
4913}
4914
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004915void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004916 sp<Connection> connection = commandEntry->connection;
4917
4918 if (connection->status != Connection::STATUS_ZOMBIE) {
4919 mLock.unlock();
4920
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004921 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004922
4923 mLock.lock();
4924 }
4925}
4926
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004927void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004928 sp<IBinder> oldToken = commandEntry->oldToken;
4929 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004930 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004931 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004932 mLock.lock();
4933}
4934
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07004935void InputDispatcher::doNotifyAnrLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004936 sp<IBinder> token =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004937 commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004938 mLock.unlock();
4939
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05004940 const std::chrono::nanoseconds timeoutExtension =
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07004941 mPolicy->notifyAnr(commandEntry->inputApplicationHandle, token, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004942
4943 mLock.lock();
4944
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05004945 if (timeoutExtension > 0s) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004946 extendAnrTimeoutsLocked(commandEntry->inputApplicationHandle, token, timeoutExtension);
4947 } else {
4948 // stop waking up for events in this connection, it is already not responding
4949 sp<Connection> connection = getConnectionLocked(token);
4950 if (connection == nullptr) {
4951 return;
4952 }
4953 cancelEventsForAnrLocked(connection);
4954 }
4955}
4956
Chris Yea209fde2020-07-22 13:54:51 -07004957void InputDispatcher::extendAnrTimeoutsLocked(
4958 const std::shared_ptr<InputApplicationHandle>& application,
4959 const sp<IBinder>& connectionToken, std::chrono::nanoseconds timeoutExtension) {
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004960 if (connectionToken == nullptr && application != nullptr) {
4961 // The ANR happened because there's no focused window
4962 mNoFocusedWindowTimeoutTime = now() + timeoutExtension.count();
4963 mAwaitedFocusedApplication = application;
4964 }
4965
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004966 sp<Connection> connection = getConnectionLocked(connectionToken);
4967 if (connection == nullptr) {
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004968 // It's possible that the connection already disappeared. No action necessary.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004969 return;
4970 }
4971
4972 ALOGI("Raised ANR, but the policy wants to keep waiting on %s for %" PRId64 "ms longer",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05004973 connection->inputChannel->getName().c_str(), millis(timeoutExtension));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004974
4975 connection->responsive = true;
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05004976 const nsecs_t newTimeout = now() + timeoutExtension.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004977 for (DispatchEntry* entry : connection->waitQueue) {
4978 if (newTimeout >= entry->timeoutTime) {
4979 // Already removed old entries when connection was marked unresponsive
4980 entry->timeoutTime = newTimeout;
4981 mAnrTracker.insert(entry->timeoutTime, connectionToken);
4982 }
4983 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004984}
4985
4986void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4987 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004988 KeyEntry& entry = *(commandEntry->keyEntry);
4989 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004990
4991 mLock.unlock();
4992
Michael Wright2b3c3302018-03-02 17:19:13 +00004993 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004994 sp<IBinder> token = commandEntry->inputChannel != nullptr
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004995 ? commandEntry->inputChannel->getConnectionToken()
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004996 : nullptr;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004997 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004998 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4999 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005000 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005001 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005002
5003 mLock.lock();
5004
5005 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005006 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005007 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005008 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005009 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005010 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5011 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005012 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005013}
5014
chaviwfd6d3512019-03-25 13:23:49 -07005015void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5016 mLock.unlock();
5017 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5018 mLock.lock();
5019}
5020
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005021/**
5022 * Connection is responsive if it has no events in the waitQueue that are older than the
5023 * current time.
5024 */
5025static bool isConnectionResponsive(const Connection& connection) {
5026 const nsecs_t currentTime = now();
5027 for (const DispatchEntry* entry : connection.waitQueue) {
5028 if (entry->timeoutTime < currentTime) {
5029 return false;
5030 }
5031 }
5032 return true;
5033}
5034
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005035void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005036 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005037 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005038 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005039 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005040
5041 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005042 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005043 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005044 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005045 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005046 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005047 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005048 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005049 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5050 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005051 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005052 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005053
5054 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005055 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005056 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005057 restartEvent =
5058 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005059 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005060 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005061 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5062 handled);
5063 } else {
5064 restartEvent = false;
5065 }
5066
5067 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005068 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005069 // contents of the wait queue to have been drained, so we need to double-check
5070 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005071 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5072 if (dispatchEntryIt != connection->waitQueue.end()) {
5073 dispatchEntry = *dispatchEntryIt;
5074 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005075 mAnrTracker.erase(dispatchEntry->timeoutTime,
5076 connection->inputChannel->getConnectionToken());
5077 if (!connection->responsive) {
5078 connection->responsive = isConnectionResponsive(*connection);
5079 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005080 traceWaitQueueLength(connection);
5081 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005082 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005083 traceOutboundQueueLength(connection);
5084 } else {
5085 releaseDispatchEntry(dispatchEntry);
5086 }
5087 }
5088
5089 // Start the next dispatch cycle for this connection.
5090 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005091}
5092
5093bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005094 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005095 KeyEntry& keyEntry, bool handled) {
5096 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005097 if (!handled) {
5098 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005099 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005100 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005101 return false;
5102 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005103
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005104 // Get the fallback key state.
5105 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005106 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005107 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005108 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005109 connection->inputState.removeFallbackKey(originalKeyCode);
5110 }
5111
5112 if (handled || !dispatchEntry->hasForegroundTarget()) {
5113 // If the application handles the original key for which we previously
5114 // generated a fallback or if the window is not a foreground window,
5115 // then cancel the associated fallback key, if any.
5116 if (fallbackKeyCode != -1) {
5117 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005118#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005119 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005120 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005121 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005122#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005123 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005124 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005125
5126 mLock.unlock();
5127
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005128 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005129 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005130
5131 mLock.lock();
5132
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005133 // Cancel the fallback key.
5134 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005135 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005136 "application handled the original non-fallback key "
5137 "or is no longer a foreground target, "
5138 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005139 options.keyCode = fallbackKeyCode;
5140 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005141 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005142 connection->inputState.removeFallbackKey(originalKeyCode);
5143 }
5144 } else {
5145 // If the application did not handle a non-fallback key, first check
5146 // that we are in a good state to perform unhandled key event processing
5147 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005148 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005149 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005150#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005151 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005152 "since this is not an initial down. "
5153 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005154 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005155#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005156 return false;
5157 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005158
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005159 // Dispatch the unhandled key to the policy.
5160#if DEBUG_OUTBOUND_EVENT_DETAILS
5161 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005162 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005163 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005164#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005165 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005166
5167 mLock.unlock();
5168
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005169 bool fallback =
5170 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005171 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005172
5173 mLock.lock();
5174
5175 if (connection->status != Connection::STATUS_NORMAL) {
5176 connection->inputState.removeFallbackKey(originalKeyCode);
5177 return false;
5178 }
5179
5180 // Latch the fallback keycode for this key on an initial down.
5181 // The fallback keycode cannot change at any other point in the lifecycle.
5182 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005183 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005184 fallbackKeyCode = event.getKeyCode();
5185 } else {
5186 fallbackKeyCode = AKEYCODE_UNKNOWN;
5187 }
5188 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5189 }
5190
5191 ALOG_ASSERT(fallbackKeyCode != -1);
5192
5193 // Cancel the fallback key if the policy decides not to send it anymore.
5194 // We will continue to dispatch the key to the policy but we will no
5195 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005196 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5197 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005198#if DEBUG_OUTBOUND_EVENT_DETAILS
5199 if (fallback) {
5200 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005201 "as a fallback for %d, but on the DOWN it had requested "
5202 "to send %d instead. Fallback canceled.",
5203 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005204 } else {
5205 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005206 "but on the DOWN it had requested to send %d. "
5207 "Fallback canceled.",
5208 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005209 }
5210#endif
5211
5212 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5213 "canceling fallback, policy no longer desires it");
5214 options.keyCode = fallbackKeyCode;
5215 synthesizeCancelationEventsForConnectionLocked(connection, options);
5216
5217 fallback = false;
5218 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005219 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005220 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005221 }
5222 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005223
5224#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005225 {
5226 std::string msg;
5227 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5228 connection->inputState.getFallbackKeys();
5229 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005230 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005231 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005232 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005233 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005234 }
5235#endif
5236
5237 if (fallback) {
5238 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005239 keyEntry.eventTime = event.getEventTime();
5240 keyEntry.deviceId = event.getDeviceId();
5241 keyEntry.source = event.getSource();
5242 keyEntry.displayId = event.getDisplayId();
5243 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5244 keyEntry.keyCode = fallbackKeyCode;
5245 keyEntry.scanCode = event.getScanCode();
5246 keyEntry.metaState = event.getMetaState();
5247 keyEntry.repeatCount = event.getRepeatCount();
5248 keyEntry.downTime = event.getDownTime();
5249 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005250
5251#if DEBUG_OUTBOUND_EVENT_DETAILS
5252 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005253 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005254 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005255#endif
5256 return true; // restart the event
5257 } else {
5258#if DEBUG_OUTBOUND_EVENT_DETAILS
5259 ALOGD("Unhandled key event: No fallback key.");
5260#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005261
5262 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005263 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005264 }
5265 }
5266 return false;
5267}
5268
5269bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005270 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005271 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005272 return false;
5273}
5274
5275void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5276 mLock.unlock();
5277
5278 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5279
5280 mLock.lock();
5281}
5282
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005283KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
5284 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08005285 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08005286 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
5287 entry.repeatCount, entry.downTime, entry.eventTime);
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005288 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005289}
5290
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005291void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5292 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005293 // TODO Write some statistics about how long we spend waiting.
5294}
5295
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005296/**
5297 * Report the touch event latency to the statsd server.
5298 * Input events are reported for statistics if:
5299 * - This is a touchscreen event
5300 * - InputFilter is not enabled
5301 * - Event is not injected or synthesized
5302 *
5303 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5304 * from getting aggregated with the "old" data.
5305 */
5306void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5307 REQUIRES(mLock) {
5308 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5309 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5310 if (!reportForStatistics) {
5311 return;
5312 }
5313
5314 if (mTouchStatistics.shouldReport()) {
5315 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5316 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5317 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5318 mTouchStatistics.reset();
5319 }
5320 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5321 mTouchStatistics.addValue(latencyMicros);
5322}
5323
Michael Wrightd02c5b62014-02-10 15:10:22 -08005324void InputDispatcher::traceInboundQueueLengthLocked() {
5325 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005326 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005327 }
5328}
5329
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005330void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005331 if (ATRACE_ENABLED()) {
5332 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005333 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005334 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005335 }
5336}
5337
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005338void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005339 if (ATRACE_ENABLED()) {
5340 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005341 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005342 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005343 }
5344}
5345
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005346void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005347 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005348
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005349 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005350 dumpDispatchStateLocked(dump);
5351
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005352 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005353 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005354 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005355 }
5356}
5357
5358void InputDispatcher::monitor() {
5359 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005360 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005361 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005362 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005363}
5364
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005365/**
5366 * Wake up the dispatcher and wait until it processes all events and commands.
5367 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5368 * this method can be safely called from any thread, as long as you've ensured that
5369 * the work you are interested in completing has already been queued.
5370 */
5371bool InputDispatcher::waitForIdle() {
5372 /**
5373 * Timeout should represent the longest possible time that a device might spend processing
5374 * events and commands.
5375 */
5376 constexpr std::chrono::duration TIMEOUT = 100ms;
5377 std::unique_lock lock(mLock);
5378 mLooper->wake();
5379 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5380 return result == std::cv_status::no_timeout;
5381}
5382
Vishnu Naire798b472020-07-23 13:52:21 -07005383/**
5384 * Sets focus to the window identified by the token. This must be called
5385 * after updating any input window handles.
5386 *
5387 * Params:
5388 * request.token - input channel token used to identify the window that should gain focus.
5389 * request.focusedToken - the token that the caller expects currently to be focused. If the
5390 * specified token does not match the currently focused window, this request will be dropped.
5391 * If the specified focused token matches the currently focused window, the call will succeed.
5392 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5393 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5394 * when requesting the focus change. This determines which request gets
5395 * precedence if there is a focus change request from another source such as pointer down.
5396 */
Vishnu Nair958da932020-08-21 17:12:37 -07005397void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5398 { // acquire lock
5399 std::scoped_lock _l(mLock);
5400
5401 const int32_t displayId = request.displayId;
5402 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5403 if (request.focusedToken && oldFocusedToken != request.focusedToken) {
5404 ALOGD_IF(DEBUG_FOCUS,
5405 "setFocusedWindow on display %" PRId32
5406 " ignored, reason: focusedToken is not focused",
5407 displayId);
5408 return;
5409 }
5410
5411 mPendingFocusRequests.erase(displayId);
5412 FocusResult result = handleFocusRequestLocked(request);
5413 if (result == FocusResult::NOT_VISIBLE) {
5414 // The requested window is not currently visible. Wait for the window to become visible
5415 // and then provide it focus. This is to handle situations where a user action triggers
5416 // a new window to appear. We want to be able to queue any key events after the user
5417 // action and deliver it to the newly focused window. In order for this to happen, we
5418 // take focus from the currently focused window so key events can be queued.
5419 ALOGD_IF(DEBUG_FOCUS,
5420 "setFocusedWindow on display %" PRId32
5421 " pending, reason: window is not visible",
5422 displayId);
5423 mPendingFocusRequests[displayId] = request;
5424 onFocusChangedLocked(oldFocusedToken, nullptr, displayId,
5425 "setFocusedWindow_AwaitingWindowVisibility");
5426 } else if (result != FocusResult::OK) {
5427 ALOGW("setFocusedWindow on display %" PRId32 " ignored, reason:%s", displayId,
5428 typeToString(result));
5429 }
5430 } // release lock
5431 // Wake up poll loop since it may need to make new input dispatching choices.
5432 mLooper->wake();
5433}
5434
5435InputDispatcher::FocusResult InputDispatcher::handleFocusRequestLocked(
5436 const FocusRequest& request) {
5437 const int32_t displayId = request.displayId;
5438 const sp<IBinder> newFocusedToken = request.token;
5439 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5440
5441 if (oldFocusedToken == request.token) {
5442 ALOGD_IF(DEBUG_FOCUS,
5443 "setFocusedWindow on display %" PRId32 " ignored, reason: already focused",
5444 displayId);
5445 return FocusResult::OK;
5446 }
5447
5448 FocusResult result = checkTokenFocusableLocked(newFocusedToken, displayId);
5449 if (result != FocusResult::OK) {
5450 return result;
5451 }
5452
5453 std::string_view reason =
5454 (request.focusedToken) ? "setFocusedWindow_FocusCheck" : "setFocusedWindow";
5455 onFocusChangedLocked(oldFocusedToken, newFocusedToken, displayId, reason);
5456 return FocusResult::OK;
5457}
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005458
Vishnu Nairad321cd2020-08-20 16:40:21 -07005459void InputDispatcher::onFocusChangedLocked(const sp<IBinder>& oldFocusedToken,
5460 const sp<IBinder>& newFocusedToken, int32_t displayId,
5461 std::string_view reason) {
5462 if (oldFocusedToken) {
5463 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(oldFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005464 if (focusedInputChannel) {
5465 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5466 "focus left window");
5467 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005468 enqueueFocusEventLocked(oldFocusedToken, false /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005469 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005470 mFocusedWindowTokenByDisplay.erase(displayId);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005471 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005472 if (newFocusedToken) {
5473 mFocusedWindowTokenByDisplay[displayId] = newFocusedToken;
5474 enqueueFocusEventLocked(newFocusedToken, true /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005475 }
5476
5477 if (mFocusedDisplayId == displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005478 notifyFocusChangedLocked(oldFocusedToken, newFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005479 }
5480}
Vishnu Nair958da932020-08-21 17:12:37 -07005481
5482/**
5483 * Checks if the window token can be focused on a display. The token can be focused if there is
5484 * at least one window handle that is visible with the same token and all window handles with the
5485 * same token are focusable.
5486 *
5487 * In the case of mirroring, two windows may share the same window token and their visibility
5488 * might be different. Example, the mirrored window can cover the window its mirroring. However,
5489 * we expect the focusability of the windows to match since its hard to reason why one window can
5490 * receive focus events and the other cannot when both are backed by the same input channel.
5491 */
5492InputDispatcher::FocusResult InputDispatcher::checkTokenFocusableLocked(const sp<IBinder>& token,
5493 int32_t displayId) const {
5494 bool allWindowsAreFocusable = true;
5495 bool visibleWindowFound = false;
5496 bool windowFound = false;
5497 for (const sp<InputWindowHandle>& window : getWindowHandlesLocked(displayId)) {
5498 if (window->getToken() != token) {
5499 continue;
5500 }
5501 windowFound = true;
5502 if (window->getInfo()->visible) {
5503 // Check if at least a single window is visible.
5504 visibleWindowFound = true;
5505 }
5506 if (!window->getInfo()->focusable) {
5507 // Check if all windows with the window token are focusable.
5508 allWindowsAreFocusable = false;
5509 break;
5510 }
5511 }
5512
5513 if (!windowFound) {
5514 return FocusResult::NO_WINDOW;
5515 }
5516 if (!allWindowsAreFocusable) {
5517 return FocusResult::NOT_FOCUSABLE;
5518 }
5519 if (!visibleWindowFound) {
5520 return FocusResult::NOT_VISIBLE;
5521 }
5522
5523 return FocusResult::OK;
5524}
Garfield Tane84e6f92019-08-29 17:28:41 -07005525} // namespace android::inputdispatcher