blob: 3135c192145adaa54b7d94af2b4ef40c0e813630 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
Garfield Tan15601662020-09-22 15:32:38 -070031// Log debug messages about channel creation
32#define DEBUG_CHANNEL_CREATION 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080033
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
Siarhei Vishniakou86587282019-09-09 18:20:15 +010038static constexpr bool DEBUG_FOCUS = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -080039
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +000040// Log debug messages about touch occlusion
41// STOPSHIP(b/169067926): Set to false
42static constexpr bool DEBUG_TOUCH_OCCLUSION = true;
43
Michael Wrightd02c5b62014-02-10 15:10:22 -080044// Log debug messages about the app switch latency optimization.
45#define DEBUG_APP_SWITCH 0
46
47// Log debug messages about hover events.
48#define DEBUG_HOVER 0
49
50#include "InputDispatcher.h"
51
Michael Wright2b3c3302018-03-02 17:19:13 +000052#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080053#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050054#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070055#include <binder/Binder.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080056#include <input/InputDevice.h>
Michael Wright44753b12020-07-08 13:48:11 +010057#include <input/InputWindow.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070058#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000059#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070060#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010061#include <statslog.h>
62#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070063#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080064
Michael Wright44753b12020-07-08 13:48:11 +010065#include <cerrno>
66#include <cinttypes>
67#include <climits>
68#include <cstddef>
69#include <ctime>
70#include <queue>
71#include <sstream>
72
73#include "Connection.h"
74
Michael Wrightd02c5b62014-02-10 15:10:22 -080075#define INDENT " "
76#define INDENT2 " "
77#define INDENT3 " "
78#define INDENT4 " "
79
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080080using android::base::StringPrintf;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080081using android::os::BlockUntrustedTouchesMode;
82using android::os::InputEventInjectionResult;
83using android::os::InputEventInjectionSync;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080084
Garfield Tane84e6f92019-08-29 17:28:41 -070085namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080086
87// Default input dispatching timeout if there is no focused application or paused window
88// from which to determine an appropriate dispatching timeout.
Siarhei Vishniakou70622952020-07-30 11:17:23 -050089constexpr std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT =
90 std::chrono::milliseconds(android::os::IInputConstants::DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
Michael Wrightd02c5b62014-02-10 15:10:22 -080091
92// Amount of time to allow for all pending events to be processed when an app switch
93// key is on the way. This is used to preempt input dispatch and drop input events
94// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000095constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080096
97// Amount of time to allow for an event to be dispatched (measured since its eventTime)
98// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000099constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800100
Michael Wrightd02c5b62014-02-10 15:10:22 -0800101// 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 +0000102constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
103
104// Log a warning when an interception call takes longer than this to process.
105constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800106
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700107// Additional key latency in case a connection is still processing some motion events.
108// This will help with the case when a user touched a button that opens a new window,
109// and gives us the chance to dispatch the key to this new window.
110constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
111
Michael Wrightd02c5b62014-02-10 15:10:22 -0800112// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000113constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
114
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000115// Event log tags. See EventLogTags.logtags for reference
116constexpr int LOGTAG_INPUT_INTERACTION = 62000;
117constexpr int LOGTAG_INPUT_FOCUS = 62001;
118
Michael Wrightd02c5b62014-02-10 15:10:22 -0800119static inline nsecs_t now() {
120 return systemTime(SYSTEM_TIME_MONOTONIC);
121}
122
123static inline const char* toString(bool value) {
124 return value ? "true" : "false";
125}
126
127static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700128 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
129 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800130}
131
132static bool isValidKeyAction(int32_t action) {
133 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700134 case AKEY_EVENT_ACTION_DOWN:
135 case AKEY_EVENT_ACTION_UP:
136 return true;
137 default:
138 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800139 }
140}
141
142static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700143 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800144 ALOGE("Key event has invalid action code 0x%x", action);
145 return false;
146 }
147 return true;
148}
149
Michael Wright7b159c92015-05-14 14:48:03 +0100150static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800151 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700152 case AMOTION_EVENT_ACTION_DOWN:
153 case AMOTION_EVENT_ACTION_UP:
154 case AMOTION_EVENT_ACTION_CANCEL:
155 case AMOTION_EVENT_ACTION_MOVE:
156 case AMOTION_EVENT_ACTION_OUTSIDE:
157 case AMOTION_EVENT_ACTION_HOVER_ENTER:
158 case AMOTION_EVENT_ACTION_HOVER_MOVE:
159 case AMOTION_EVENT_ACTION_HOVER_EXIT:
160 case AMOTION_EVENT_ACTION_SCROLL:
161 return true;
162 case AMOTION_EVENT_ACTION_POINTER_DOWN:
163 case AMOTION_EVENT_ACTION_POINTER_UP: {
164 int32_t index = getMotionEventActionPointerIndex(action);
165 return index >= 0 && index < pointerCount;
166 }
167 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
168 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
169 return actionButton != 0;
170 default:
171 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800172 }
173}
174
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500175static int64_t millis(std::chrono::nanoseconds t) {
176 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
177}
178
Michael Wright7b159c92015-05-14 14:48:03 +0100179static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700180 const PointerProperties* pointerProperties) {
181 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800182 ALOGE("Motion event has invalid action code 0x%x", action);
183 return false;
184 }
185 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000186 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700187 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800188 return false;
189 }
190 BitSet32 pointerIdBits;
191 for (size_t i = 0; i < pointerCount; i++) {
192 int32_t id = pointerProperties[i].id;
193 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700194 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
195 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800196 return false;
197 }
198 if (pointerIdBits.hasBit(id)) {
199 ALOGE("Motion event has duplicate pointer id %d", id);
200 return false;
201 }
202 pointerIdBits.markBit(id);
203 }
204 return true;
205}
206
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800207static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800208 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800209 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800210 return;
211 }
212
213 bool first = true;
214 Region::const_iterator cur = region.begin();
215 Region::const_iterator const tail = region.end();
216 while (cur != tail) {
217 if (first) {
218 first = false;
219 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800220 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800221 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800222 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800223 cur++;
224 }
225}
226
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500227static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
228 constexpr size_t maxEntries = 50; // max events to print
229 constexpr size_t skipBegin = maxEntries / 2;
230 const size_t skipEnd = queue.size() - maxEntries / 2;
231 // skip from maxEntries / 2 ... size() - maxEntries/2
232 // only print from 0 .. skipBegin and then from skipEnd .. size()
233
234 std::string dump;
235 for (size_t i = 0; i < queue.size(); i++) {
236 const DispatchEntry& entry = *queue[i];
237 if (i >= skipBegin && i < skipEnd) {
238 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
239 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
240 continue;
241 }
242 dump.append(INDENT4);
243 dump += entry.eventEntry->getDescription();
244 dump += StringPrintf(", seq=%" PRIu32
245 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
246 entry.seq, entry.targetFlags, entry.resolvedAction,
247 ns2ms(currentTime - entry.eventEntry->eventTime));
248 if (entry.deliveryTime != 0) {
249 // This entry was delivered, so add information on how long we've been waiting
250 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
251 }
252 dump.append("\n");
253 }
254 return dump;
255}
256
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700257/**
258 * Find the entry in std::unordered_map by key, and return it.
259 * If the entry is not found, return a default constructed entry.
260 *
261 * Useful when the entries are vectors, since an empty vector will be returned
262 * if the entry is not found.
263 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
264 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700265template <typename K, typename V>
266static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700267 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700268 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800269}
270
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700271/**
272 * Find the entry in std::unordered_map by value, and remove it.
273 * If more than one entry has the same value, then all matching
274 * key-value pairs will be removed.
275 *
276 * Return true if at least one value has been removed.
277 */
278template <typename K, typename V>
279static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
280 bool removed = false;
281 for (auto it = map.begin(); it != map.end();) {
282 if (it->second == value) {
283 it = map.erase(it);
284 removed = true;
285 } else {
286 it++;
287 }
288 }
289 return removed;
290}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800291
Vishnu Nair958da932020-08-21 17:12:37 -0700292/**
293 * Find the entry in std::unordered_map by key and return the value as an optional.
294 */
295template <typename K, typename V>
296static std::optional<V> getOptionalValueByKey(const std::unordered_map<K, V>& map, K key) {
297 auto it = map.find(key);
298 return it != map.end() ? std::optional<V>{it->second} : std::nullopt;
299}
300
chaviwaf87b3e2019-10-01 16:59:28 -0700301static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
302 if (first == second) {
303 return true;
304 }
305
306 if (first == nullptr || second == nullptr) {
307 return false;
308 }
309
310 return first->getToken() == second->getToken();
311}
312
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800313static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
314 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
315}
316
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000317static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700318 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000319 int32_t inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700320 if (inputTarget.useDefaultPointerTransform()) {
321 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700322 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
chaviw1ff3d1e2020-07-01 15:53:47 -0700323 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000324 }
325
326 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
327 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
328
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700329 std::vector<PointerCoords> pointerCoords;
330 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000331
332 // Use the first pointer information to normalize all other pointers. This could be any pointer
333 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700334 // uses the transform for the normalized pointer.
335 const ui::Transform& firstPointerTransform =
336 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
337 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000338
339 // Iterate through all pointers in the event to normalize against the first.
340 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
341 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
342 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700343 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000344
345 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700346 // First, apply the current pointer's transform to update the coordinates into
347 // window space.
348 pointerCoords[pointerIndex].transform(currTransform);
349 // Next, apply the inverse transform of the normalized coordinates so the
350 // current coordinates are transformed into the normalized coordinate space.
351 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000352 }
353
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700354 std::unique_ptr<MotionEntry> combinedMotionEntry =
355 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
356 motionEntry.deviceId, motionEntry.source,
357 motionEntry.displayId, motionEntry.policyFlags,
358 motionEntry.action, motionEntry.actionButton,
359 motionEntry.flags, motionEntry.metaState,
360 motionEntry.buttonState, motionEntry.classification,
361 motionEntry.edgeFlags, motionEntry.xPrecision,
362 motionEntry.yPrecision, motionEntry.xCursorPosition,
363 motionEntry.yCursorPosition, motionEntry.downTime,
364 motionEntry.pointerCount, motionEntry.pointerProperties,
365 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000366
367 if (motionEntry.injectionState) {
368 combinedMotionEntry->injectionState = motionEntry.injectionState;
369 combinedMotionEntry->injectionState->refCount += 1;
370 }
371
372 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700373 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
374 firstPointerTransform, inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000375 return dispatchEntry;
376}
377
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700378static void addGestureMonitors(const std::vector<Monitor>& monitors,
379 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
380 float yOffset = 0) {
381 if (monitors.empty()) {
382 return;
383 }
384 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
385 for (const Monitor& monitor : monitors) {
386 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
387 }
388}
389
Garfield Tan15601662020-09-22 15:32:38 -0700390static status_t openInputChannelPair(const std::string& name,
391 std::shared_ptr<InputChannel>& serverChannel,
392 std::unique_ptr<InputChannel>& clientChannel) {
393 std::unique_ptr<InputChannel> uniqueServerChannel;
394 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
395
396 serverChannel = std::move(uniqueServerChannel);
397 return result;
398}
399
Vishnu Nair958da932020-08-21 17:12:37 -0700400const char* InputDispatcher::typeToString(InputDispatcher::FocusResult result) {
401 switch (result) {
402 case InputDispatcher::FocusResult::OK:
403 return "Ok";
404 case InputDispatcher::FocusResult::NO_WINDOW:
405 return "Window not found";
406 case InputDispatcher::FocusResult::NOT_FOCUSABLE:
407 return "Window not focusable";
408 case InputDispatcher::FocusResult::NOT_VISIBLE:
409 return "Window not visible";
410 }
411}
412
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500413template <typename T>
414static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
415 if (lhs == nullptr && rhs == nullptr) {
416 return true;
417 }
418 if (lhs == nullptr || rhs == nullptr) {
419 return false;
420 }
421 return *lhs == *rhs;
422}
423
Michael Wrightd02c5b62014-02-10 15:10:22 -0800424// --- InputDispatcher ---
425
Garfield Tan00f511d2019-06-12 16:55:40 -0700426InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
427 : mPolicy(policy),
428 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700429 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800430 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700431 mAppSwitchSawKeyDown(false),
432 mAppSwitchDueTime(LONG_LONG_MAX),
433 mNextUnblockedEvent(nullptr),
434 mDispatchEnabled(false),
435 mDispatchFrozen(false),
436 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800437 // mInTouchMode will be initialized by the WindowManager to the default device config.
438 // To avoid leaking stack in case that call never comes, and for tests,
439 // initialize it here anyways.
440 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100441 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700442 mFocusedDisplayId(ADISPLAY_ID_DEFAULT) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800443 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800444 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800445
Yi Kong9b14ac62018-07-17 13:48:38 -0700446 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800447
448 policy->getDispatcherConfiguration(&mConfig);
449}
450
451InputDispatcher::~InputDispatcher() {
452 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800453 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800454
455 resetKeyRepeatLocked();
456 releasePendingEventLocked();
457 drainInboundQueueLocked();
458 }
459
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700460 while (!mConnectionsByFd.empty()) {
461 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700462 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800463 }
464}
465
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700466status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700467 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700468 return ALREADY_EXISTS;
469 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700470 mThread = std::make_unique<InputThread>(
471 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
472 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700473}
474
475status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700476 if (mThread && mThread->isCallingThread()) {
477 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700478 return INVALID_OPERATION;
479 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700480 mThread.reset();
481 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700482}
483
Michael Wrightd02c5b62014-02-10 15:10:22 -0800484void InputDispatcher::dispatchOnce() {
485 nsecs_t nextWakeupTime = LONG_LONG_MAX;
486 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800487 std::scoped_lock _l(mLock);
488 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800489
490 // Run a dispatch loop if there are no pending commands.
491 // The dispatch loop might enqueue commands to run afterwards.
492 if (!haveCommandsLocked()) {
493 dispatchOnceInnerLocked(&nextWakeupTime);
494 }
495
496 // Run all pending commands if there are any.
497 // If any commands were run then force the next poll to wake up immediately.
498 if (runCommandsLockedInterruptible()) {
499 nextWakeupTime = LONG_LONG_MIN;
500 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800501
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700502 // If we are still waiting for ack on some events,
503 // we might have to wake up earlier to check if an app is anr'ing.
504 const nsecs_t nextAnrCheck = processAnrsLocked();
505 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
506
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800507 // We are about to enter an infinitely long sleep, because we have no commands or
508 // pending or queued events
509 if (nextWakeupTime == LONG_LONG_MAX) {
510 mDispatcherEnteredIdle.notify_all();
511 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800512 } // release lock
513
514 // Wait for callback or timeout or wake. (make sure we round up, not down)
515 nsecs_t currentTime = now();
516 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
517 mLooper->pollOnce(timeoutMillis);
518}
519
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700520/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500521 * Raise ANR if there is no focused window.
522 * Before the ANR is raised, do a final state check:
523 * 1. The currently focused application must be the same one we are waiting for.
524 * 2. Ensure we still don't have a focused window.
525 */
526void InputDispatcher::processNoFocusedWindowAnrLocked() {
527 // Check if the application that we are waiting for is still focused.
528 std::shared_ptr<InputApplicationHandle> focusedApplication =
529 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
530 if (focusedApplication == nullptr ||
531 focusedApplication->getApplicationToken() !=
532 mAwaitedFocusedApplication->getApplicationToken()) {
533 // Unexpected because we should have reset the ANR timer when focused application changed
534 ALOGE("Waited for a focused window, but focused application has already changed to %s",
535 focusedApplication->getName().c_str());
536 return; // The focused application has changed.
537 }
538
539 const sp<InputWindowHandle>& focusedWindowHandle =
540 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
541 if (focusedWindowHandle != nullptr) {
542 return; // We now have a focused window. No need for ANR.
543 }
544 onAnrLocked(mAwaitedFocusedApplication);
545}
546
547/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700548 * Check if any of the connections' wait queues have events that are too old.
549 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
550 * Return the time at which we should wake up next.
551 */
552nsecs_t InputDispatcher::processAnrsLocked() {
553 const nsecs_t currentTime = now();
554 nsecs_t nextAnrCheck = LONG_LONG_MAX;
555 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
556 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
557 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500558 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700559 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500560 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700561 return LONG_LONG_MIN;
562 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500563 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700564 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
565 }
566 }
567
568 // Check if any connection ANRs are due
569 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
570 if (currentTime < nextAnrCheck) { // most likely scenario
571 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
572 }
573
574 // If we reached here, we have an unresponsive connection.
575 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
576 if (connection == nullptr) {
577 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
578 return nextAnrCheck;
579 }
580 connection->responsive = false;
581 // Stop waking up for this unresponsive connection
582 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -0500583 onAnrLocked(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700584 return LONG_LONG_MIN;
585}
586
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500587std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700588 sp<InputWindowHandle> window = getWindowHandleLocked(token);
589 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500590 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700591 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500592 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700593}
594
Michael Wrightd02c5b62014-02-10 15:10:22 -0800595void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
596 nsecs_t currentTime = now();
597
Jeff Browndc5992e2014-04-11 01:27:26 -0700598 // Reset the key repeat timer whenever normal dispatch is suspended while the
599 // device is in a non-interactive state. This is to ensure that we abort a key
600 // repeat if the device is just coming out of sleep.
601 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800602 resetKeyRepeatLocked();
603 }
604
605 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
606 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100607 if (DEBUG_FOCUS) {
608 ALOGD("Dispatch frozen. Waiting some more.");
609 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800610 return;
611 }
612
613 // Optimize latency of app switches.
614 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
615 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
616 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
617 if (mAppSwitchDueTime < *nextWakeupTime) {
618 *nextWakeupTime = mAppSwitchDueTime;
619 }
620
621 // Ready to start a new event.
622 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700623 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700624 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800625 if (isAppSwitchDue) {
626 // The inbound queue is empty so the app switch key we were waiting
627 // for will never arrive. Stop waiting for it.
628 resetPendingAppSwitchLocked(false);
629 isAppSwitchDue = false;
630 }
631
632 // Synthesize a key repeat if appropriate.
633 if (mKeyRepeatState.lastKeyEntry) {
634 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
635 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
636 } else {
637 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
638 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
639 }
640 }
641 }
642
643 // Nothing to do if there is no pending event.
644 if (!mPendingEvent) {
645 return;
646 }
647 } else {
648 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700649 mPendingEvent = mInboundQueue.front();
650 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800651 traceInboundQueueLengthLocked();
652 }
653
654 // Poke user activity for this event.
655 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700656 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800657 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800658 }
659
660 // Now we have an event to dispatch.
661 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700662 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800663 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700664 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800665 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700666 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800667 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700668 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800669 }
670
671 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700672 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800673 }
674
675 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700676 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700677 const ConfigurationChangedEntry& typedEntry =
678 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700679 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700680 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700681 break;
682 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800683
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700684 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700685 const DeviceResetEntry& typedEntry =
686 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700687 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700688 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700689 break;
690 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800691
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100692 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700693 std::shared_ptr<FocusEntry> typedEntry =
694 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100695 dispatchFocusLocked(currentTime, typedEntry);
696 done = true;
697 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
698 break;
699 }
700
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700701 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700702 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700703 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700704 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700705 resetPendingAppSwitchLocked(true);
706 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700707 } else if (dropReason == DropReason::NOT_DROPPED) {
708 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700709 }
710 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700711 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700712 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700713 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700714 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
715 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700716 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700717 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700718 break;
719 }
720
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700721 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700722 std::shared_ptr<MotionEntry> motionEntry =
723 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700724 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
725 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800726 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700727 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700728 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700729 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700730 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
731 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700732 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700733 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700734 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800735 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800736 }
737
738 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700739 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700740 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800741 }
Michael Wright3a981722015-06-10 15:26:13 +0100742 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800743
744 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700745 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800746 }
747}
748
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700749/**
750 * Return true if the events preceding this incoming motion event should be dropped
751 * Return false otherwise (the default behaviour)
752 */
753bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700754 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700755 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700756
757 // Optimize case where the current application is unresponsive and the user
758 // decides to touch a window in a different application.
759 // If the application takes too long to catch up then we drop all events preceding
760 // the touch into the other window.
761 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700762 int32_t displayId = motionEntry.displayId;
763 int32_t x = static_cast<int32_t>(
764 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
765 int32_t y = static_cast<int32_t>(
766 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
767 sp<InputWindowHandle> touchedWindowHandle =
768 findTouchedWindowAtLocked(displayId, x, y, nullptr);
769 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700770 touchedWindowHandle->getApplicationToken() !=
771 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700772 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700773 ALOGI("Pruning input queue because user touched a different application while waiting "
774 "for %s",
775 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700776 return true;
777 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700778
779 // Alternatively, maybe there's a gesture monitor that could handle this event
780 std::vector<TouchedMonitor> gestureMonitors =
781 findTouchedGestureMonitorsLocked(displayId, {});
782 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
783 sp<Connection> connection =
784 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000785 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700786 // This monitor could take more input. Drop all events preceding this
787 // event, so that gesture monitor could get a chance to receive the stream
788 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
789 "responsive gesture monitor that may handle the event",
790 mAwaitedFocusedApplication->getName().c_str());
791 return true;
792 }
793 }
794 }
795
796 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
797 // yet been processed by some connections, the dispatcher will wait for these motion
798 // events to be processed before dispatching the key event. This is because these motion events
799 // may cause a new window to be launched, which the user might expect to receive focus.
800 // To prevent waiting forever for such events, just send the key to the currently focused window
801 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
802 ALOGD("Received a new pointer down event, stop waiting for events to process and "
803 "just send the pending key event to the focused window.");
804 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700805 }
806 return false;
807}
808
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700809bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700810 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700811 mInboundQueue.push_back(std::move(newEntry));
812 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800813 traceInboundQueueLengthLocked();
814
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700815 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700816 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700817 // Optimize app switch latency.
818 // If the application takes too long to catch up then we drop all events preceding
819 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700820 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700821 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700822 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700823 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700824 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700825 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800826#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700827 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800828#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700829 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700830 mAppSwitchSawKeyDown = false;
831 needWake = true;
832 }
833 }
834 }
835 break;
836 }
837
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700838 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700839 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
840 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700841 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800842 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700843 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800844 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100845 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700846 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
847 break;
848 }
849 case EventEntry::Type::CONFIGURATION_CHANGED:
850 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700851 // nothing to do
852 break;
853 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800854 }
855
856 return needWake;
857}
858
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700859void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700860 mRecentQueue.push_back(entry);
861 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700862 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800863 }
864}
865
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700866sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700867 int32_t y, TouchState* touchState,
868 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700869 bool addPortalWindows) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700870 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
871 LOG_ALWAYS_FATAL(
872 "Must provide a valid touch state if adding portal windows or outside targets");
873 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800874 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700875 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800876 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800877 const InputWindowInfo* windowInfo = windowHandle->getInfo();
878 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100879 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800880
881 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100882 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
883 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
884 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800885 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800886 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700887 if (portalToDisplayId != ADISPLAY_ID_NONE &&
888 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800889 if (addPortalWindows) {
890 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700891 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800892 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700893 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700894 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800895 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800896 // Found window.
897 return windowHandle;
898 }
899 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800900
Michael Wright44753b12020-07-08 13:48:11 +0100901 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700902 touchState->addOrUpdateWindow(windowHandle,
903 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
904 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800905 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800906 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800907 }
908 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700909 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800910}
911
Garfield Tane84e6f92019-08-29 17:28:41 -0700912std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700913 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000914 std::vector<TouchedMonitor> touchedMonitors;
915
916 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
917 addGestureMonitors(monitors, touchedMonitors);
918 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
919 const InputWindowInfo* windowInfo = portalWindow->getInfo();
920 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700921 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
922 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000923 }
924 return touchedMonitors;
925}
926
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700927void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800928 const char* reason;
929 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700930 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800931#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700932 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800933#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700934 reason = "inbound event was dropped because the policy consumed it";
935 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700936 case DropReason::DISABLED:
937 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700938 ALOGI("Dropped event because input dispatch is disabled.");
939 }
940 reason = "inbound event was dropped because input dispatch is disabled";
941 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700942 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700943 ALOGI("Dropped event because of pending overdue app switch.");
944 reason = "inbound event was dropped because of pending overdue app switch";
945 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700946 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700947 ALOGI("Dropped event because the current application is not responding and the user "
948 "has started interacting with a different application.");
949 reason = "inbound event was dropped because the current application is not responding "
950 "and the user has started interacting with a different application";
951 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700952 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700953 ALOGI("Dropped event because it is stale.");
954 reason = "inbound event was dropped because it is stale";
955 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700956 case DropReason::NOT_DROPPED: {
957 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700958 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700959 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800960 }
961
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700962 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700963 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800964 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
965 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700966 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800967 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700968 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700969 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
970 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700971 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
972 synthesizeCancelationEventsForAllConnectionsLocked(options);
973 } else {
974 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
975 synthesizeCancelationEventsForAllConnectionsLocked(options);
976 }
977 break;
978 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100979 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700980 case EventEntry::Type::CONFIGURATION_CHANGED:
981 case EventEntry::Type::DEVICE_RESET: {
982 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
983 break;
984 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985 }
986}
987
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800988static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700989 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
990 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800991}
992
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700993bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
994 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
995 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
996 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800997}
998
999bool InputDispatcher::isAppSwitchPendingLocked() {
1000 return mAppSwitchDueTime != LONG_LONG_MAX;
1001}
1002
1003void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1004 mAppSwitchDueTime = LONG_LONG_MAX;
1005
1006#if DEBUG_APP_SWITCH
1007 if (handled) {
1008 ALOGD("App switch has arrived.");
1009 } else {
1010 ALOGD("App switch was abandoned.");
1011 }
1012#endif
1013}
1014
Michael Wrightd02c5b62014-02-10 15:10:22 -08001015bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001016 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001017}
1018
1019bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001020 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001021 return false;
1022 }
1023
1024 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001025 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001026 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001027 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001028 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001029
1030 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001031 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001032 return true;
1033}
1034
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001035void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1036 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001037}
1038
1039void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001040 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001041 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001042 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001043 releaseInboundEventLocked(entry);
1044 }
1045 traceInboundQueueLengthLocked();
1046}
1047
1048void InputDispatcher::releasePendingEventLocked() {
1049 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001050 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001051 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001052 }
1053}
1054
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001055void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001056 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001057 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001058#if DEBUG_DISPATCH_CYCLE
1059 ALOGD("Injected inbound event was dropped.");
1060#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001061 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001062 }
1063 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001064 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001065 }
1066 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001067}
1068
1069void InputDispatcher::resetKeyRepeatLocked() {
1070 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001071 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001072 }
1073}
1074
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001075std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1076 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001077
Michael Wright2e732952014-09-24 13:26:59 -07001078 uint32_t policyFlags = entry->policyFlags &
1079 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001081 std::shared_ptr<KeyEntry> newEntry =
1082 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1083 entry->source, entry->displayId, policyFlags, entry->action,
1084 entry->flags, entry->keyCode, entry->scanCode,
1085 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001086
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001087 newEntry->syntheticRepeat = true;
1088 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001089 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001090 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001091}
1092
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001093bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001094 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001095#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001096 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001097#endif
1098
1099 // Reset key repeating in case a keyboard device was added or removed or something.
1100 resetKeyRepeatLocked();
1101
1102 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001103 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1104 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001105 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001106 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001107 return true;
1108}
1109
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001110bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1111 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001112#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001113 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1114 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001115#endif
1116
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001117 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001118 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001119 synthesizeCancelationEventsForAllConnectionsLocked(options);
1120 return true;
1121}
1122
Vishnu Nairad321cd2020-08-20 16:40:21 -07001123void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001124 std::string_view reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001125 if (mPendingEvent != nullptr) {
1126 // Move the pending event to the front of the queue. This will give the chance
1127 // for the pending event to get dispatched to the newly focused window
1128 mInboundQueue.push_front(mPendingEvent);
1129 mPendingEvent = nullptr;
1130 }
1131
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001132 std::unique_ptr<FocusEntry> focusEntry =
1133 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1134 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001135
1136 // This event should go to the front of the queue, but behind all other focus events
1137 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001138 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001139 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001140 [](const std::shared_ptr<EventEntry>& event) {
1141 return event->type == EventEntry::Type::FOCUS;
1142 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001143
1144 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001145 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001146}
1147
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001148void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001149 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001150 if (channel == nullptr) {
1151 return; // Window has gone away
1152 }
1153 InputTarget target;
1154 target.inputChannel = channel;
1155 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1156 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001157 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1158 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001159 std::string reason = std::string("reason=").append(entry->reason);
1160 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001161 dispatchEventLocked(currentTime, entry, {target});
1162}
1163
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001164bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001165 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001166 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001167 if (!entry->dispatchInProgress) {
1168 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1169 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1170 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1171 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001172 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001173 // We have seen two identical key downs in a row which indicates that the device
1174 // driver is automatically generating key repeats itself. We take note of the
1175 // repeat here, but we disable our own next key repeat timer since it is clear that
1176 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001177 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1178 // Make sure we don't get key down from a different device. If a different
1179 // device Id has same key pressed down, the new device Id will replace the
1180 // current one to hold the key repeat with repeat count reset.
1181 // In the future when got a KEY_UP on the device id, drop it and do not
1182 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001183 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1184 resetKeyRepeatLocked();
1185 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1186 } else {
1187 // Not a repeat. Save key down state in case we do see a repeat later.
1188 resetKeyRepeatLocked();
1189 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1190 }
1191 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001192 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1193 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001194 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001195#if DEBUG_INBOUND_EVENT_DETAILS
1196 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1197#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001198 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001199 resetKeyRepeatLocked();
1200 }
1201
1202 if (entry->repeatCount == 1) {
1203 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1204 } else {
1205 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1206 }
1207
1208 entry->dispatchInProgress = true;
1209
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001210 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001211 }
1212
1213 // Handle case where the policy asked us to try again later last time.
1214 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1215 if (currentTime < entry->interceptKeyWakeupTime) {
1216 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1217 *nextWakeupTime = entry->interceptKeyWakeupTime;
1218 }
1219 return false; // wait until next wakeup
1220 }
1221 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1222 entry->interceptKeyWakeupTime = 0;
1223 }
1224
1225 // Give the policy a chance to intercept the key.
1226 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1227 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001228 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001229 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001230 sp<IBinder> focusedWindowToken =
1231 getValueByKey(mFocusedWindowTokenByDisplay, getTargetDisplayId(*entry));
1232 if (focusedWindowToken != nullptr) {
1233 commandEntry->inputChannel = getInputChannelLocked(focusedWindowToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001234 }
1235 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001236 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001237 return false; // wait for the command to run
1238 } else {
1239 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1240 }
1241 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001242 if (*dropReason == DropReason::NOT_DROPPED) {
1243 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001244 }
1245 }
1246
1247 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001248 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001249 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001250 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1251 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001252 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001253 return true;
1254 }
1255
1256 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001257 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001258 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001259 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001260 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001261 return false;
1262 }
1263
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001264 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001265 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001266 return true;
1267 }
1268
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001269 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001270 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001271
1272 // Dispatch the key.
1273 dispatchEventLocked(currentTime, entry, inputTargets);
1274 return true;
1275}
1276
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001277void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001278#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001279 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001280 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1281 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001282 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1283 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1284 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001285#endif
1286}
1287
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001288bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001289 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001290 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001291 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001292 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001293 entry->dispatchInProgress = true;
1294
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001295 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001296 }
1297
1298 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001299 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001300 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001301 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1302 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001303 return true;
1304 }
1305
1306 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1307
1308 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001309 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001310
1311 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001312 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001313 if (isPointerEvent) {
1314 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001315 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001316 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001317 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001318 } else {
1319 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001320 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001321 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001322 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001323 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001324 return false;
1325 }
1326
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001327 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001328 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001329 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1330 return true;
1331 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001332 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001333 CancelationOptions::Mode mode(isPointerEvent
1334 ? CancelationOptions::CANCEL_POINTER_EVENTS
1335 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1336 CancelationOptions options(mode, "input event injection failed");
1337 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001338 return true;
1339 }
1340
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001341 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001342 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001343
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001344 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001345 std::unordered_map<int32_t, TouchState>::iterator it =
1346 mTouchStatesByDisplay.find(entry->displayId);
1347 if (it != mTouchStatesByDisplay.end()) {
1348 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001349 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001350 // The event has gone through these portal windows, so we add monitoring targets of
1351 // the corresponding displays as well.
1352 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001353 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001354 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001355 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001356 }
1357 }
1358 }
1359 }
1360
Michael Wrightd02c5b62014-02-10 15:10:22 -08001361 // Dispatch the motion.
1362 if (conflictingPointerActions) {
1363 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001364 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001365 synthesizeCancelationEventsForAllConnectionsLocked(options);
1366 }
1367 dispatchEventLocked(currentTime, entry, inputTargets);
1368 return true;
1369}
1370
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001371void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001372#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001373 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001374 ", policyFlags=0x%x, "
1375 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1376 "metaState=0x%x, buttonState=0x%x,"
1377 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001378 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1379 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1380 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001381
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001382 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001383 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001384 "x=%f, y=%f, pressure=%f, size=%f, "
1385 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1386 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001387 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1388 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1389 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1390 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1391 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1392 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1393 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1394 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1395 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1396 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001397 }
1398#endif
1399}
1400
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001401void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1402 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001403 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001404 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001405#if DEBUG_DISPATCH_CYCLE
1406 ALOGD("dispatchEventToCurrentInputTargets");
1407#endif
1408
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001409 updateInteractionTokensLocked(*eventEntry, inputTargets);
1410
Michael Wrightd02c5b62014-02-10 15:10:22 -08001411 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1412
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001413 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001414
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001415 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001416 sp<Connection> connection =
1417 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001418 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001419 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001420 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001421 if (DEBUG_FOCUS) {
1422 ALOGD("Dropping event delivery to target with channel '%s' because it "
1423 "is no longer registered with the input dispatcher.",
1424 inputTarget.inputChannel->getName().c_str());
1425 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001426 }
1427 }
1428}
1429
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001430void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1431 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1432 // If the policy decides to close the app, we will get a channel removal event via
1433 // unregisterInputChannel, and will clean up the connection that way. We are already not
1434 // sending new pointers to the connection when it blocked, but focused events will continue to
1435 // pile up.
1436 ALOGW("Canceling events for %s because it is unresponsive",
1437 connection->inputChannel->getName().c_str());
1438 if (connection->status == Connection::STATUS_NORMAL) {
1439 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1440 "application not responding");
1441 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001442 }
1443}
1444
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001445void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001446 if (DEBUG_FOCUS) {
1447 ALOGD("Resetting ANR timeouts.");
1448 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001449
1450 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001451 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001452 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001453}
1454
Tiger Huang721e26f2018-07-24 22:26:19 +08001455/**
1456 * Get the display id that the given event should go to. If this event specifies a valid display id,
1457 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1458 * Focused display is the display that the user most recently interacted with.
1459 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001460int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001461 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001462 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001463 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001464 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1465 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001466 break;
1467 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001468 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001469 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1470 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001471 break;
1472 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001473 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001474 case EventEntry::Type::CONFIGURATION_CHANGED:
1475 case EventEntry::Type::DEVICE_RESET: {
1476 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001477 return ADISPLAY_ID_NONE;
1478 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001479 }
1480 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1481}
1482
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001483bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1484 const char* focusedWindowName) {
1485 if (mAnrTracker.empty()) {
1486 // already processed all events that we waited for
1487 mKeyIsWaitingForEventsTimeout = std::nullopt;
1488 return false;
1489 }
1490
1491 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1492 // Start the timer
1493 ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
1494 "focus to change",
1495 focusedWindowName);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001496 mKeyIsWaitingForEventsTimeout = currentTime +
1497 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1498 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001499 return true;
1500 }
1501
1502 // We still have pending events, and already started the timer
1503 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1504 return true; // Still waiting
1505 }
1506
1507 // Waited too long, and some connection still hasn't processed all motions
1508 // Just send the key to the focused window
1509 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1510 focusedWindowName);
1511 mKeyIsWaitingForEventsTimeout = std::nullopt;
1512 return false;
1513}
1514
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001515InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1516 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1517 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001518 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001519
Tiger Huang721e26f2018-07-24 22:26:19 +08001520 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001521 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001522 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001523 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1524
Michael Wrightd02c5b62014-02-10 15:10:22 -08001525 // If there is no currently focused window and no focused application
1526 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001527 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1528 ALOGI("Dropping %s event because there is no focused window or focused application in "
1529 "display %" PRId32 ".",
1530 EventEntry::typeToString(entry.type), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001531 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001532 }
1533
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001534 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1535 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1536 // start interacting with another application via touch (app switch). This code can be removed
1537 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1538 // an app is expected to have a focused window.
1539 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1540 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1541 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001542 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1543 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1544 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001545 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001546 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001547 ALOGW("Waiting because no window has focus but %s may eventually add a "
1548 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001549 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001550 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001551 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001552 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1553 // Already raised ANR. Drop the event
1554 ALOGE("Dropping %s event because there is no focused window",
1555 EventEntry::typeToString(entry.type));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001556 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001557 } else {
1558 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001559 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001560 }
1561 }
1562
1563 // we have a valid, non-null focused window
1564 resetNoFocusedWindowTimeoutLocked();
1565
Michael Wrightd02c5b62014-02-10 15:10:22 -08001566 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001567 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001568 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001569 }
1570
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001571 if (focusedWindowHandle->getInfo()->paused) {
1572 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001573 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001574 }
1575
1576 // If the event is a key event, then we must wait for all previous events to
1577 // complete before delivering it because previous events may have the
1578 // side-effect of transferring focus to a different window and we want to
1579 // ensure that the following keys are sent to the new window.
1580 //
1581 // Suppose the user touches a button in a window then immediately presses "A".
1582 // If the button causes a pop-up window to appear then we want to ensure that
1583 // the "A" key is delivered to the new pop-up window. This is because users
1584 // often anticipate pending UI changes when typing on a keyboard.
1585 // To obtain this behavior, we must serialize key events with respect to all
1586 // prior input events.
1587 if (entry.type == EventEntry::Type::KEY) {
1588 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1589 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001590 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001591 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001592 }
1593
1594 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001595 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001596 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1597 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001598
1599 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001600 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001601}
1602
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001603/**
1604 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1605 * that are currently unresponsive.
1606 */
1607std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1608 const std::vector<TouchedMonitor>& monitors) const {
1609 std::vector<TouchedMonitor> responsiveMonitors;
1610 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1611 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1612 sp<Connection> connection = getConnectionLocked(
1613 monitor.monitor.inputChannel->getConnectionToken());
1614 if (connection == nullptr) {
1615 ALOGE("Could not find connection for monitor %s",
1616 monitor.monitor.inputChannel->getName().c_str());
1617 return false;
1618 }
1619 if (!connection->responsive) {
1620 ALOGW("Unresponsive monitor %s will not get the new gesture",
1621 connection->inputChannel->getName().c_str());
1622 return false;
1623 }
1624 return true;
1625 });
1626 return responsiveMonitors;
1627}
1628
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001629InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1630 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1631 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001632 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001633 enum InjectionPermission {
1634 INJECTION_PERMISSION_UNKNOWN,
1635 INJECTION_PERMISSION_GRANTED,
1636 INJECTION_PERMISSION_DENIED
1637 };
1638
Michael Wrightd02c5b62014-02-10 15:10:22 -08001639 // For security reasons, we defer updating the touch state until we are sure that
1640 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001641 int32_t displayId = entry.displayId;
1642 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001643 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1644
1645 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001646 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001647 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001648 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1649 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001650
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001651 // Copy current touch state into tempTouchState.
1652 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1653 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001654 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001655 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001656 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1657 mTouchStatesByDisplay.find(displayId);
1658 if (oldStateIt != mTouchStatesByDisplay.end()) {
1659 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001660 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001661 }
1662
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001663 bool isSplit = tempTouchState.split;
1664 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1665 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1666 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001667 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1668 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1669 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1670 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1671 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001672 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001673 bool wrongDevice = false;
1674 if (newGesture) {
1675 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001676 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001677 ALOGI("Dropping event because a pointer for a different device is already down "
1678 "in display %" PRId32,
1679 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001680 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001681 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001682 switchedDevice = false;
1683 wrongDevice = true;
1684 goto Failed;
1685 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001686 tempTouchState.reset();
1687 tempTouchState.down = down;
1688 tempTouchState.deviceId = entry.deviceId;
1689 tempTouchState.source = entry.source;
1690 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001691 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001692 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001693 ALOGI("Dropping move event because a pointer for a different device is already active "
1694 "in display %" PRId32,
1695 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001696 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001697 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001698 switchedDevice = false;
1699 wrongDevice = true;
1700 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001701 }
1702
1703 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1704 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1705
Garfield Tan00f511d2019-06-12 16:55:40 -07001706 int32_t x;
1707 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001708 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001709 // Always dispatch mouse events to cursor position.
1710 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001711 x = int32_t(entry.xCursorPosition);
1712 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001713 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001714 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1715 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001716 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001717 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001718 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001719 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1720 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001721
1722 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001723 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001724 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001725
Michael Wrightd02c5b62014-02-10 15:10:22 -08001726 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001727 if (newTouchedWindowHandle != nullptr &&
1728 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001729 // New window supports splitting, but we should never split mouse events.
1730 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001731 } else if (isSplit) {
1732 // New window does not support splitting but we have already split events.
1733 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001734 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001735 }
1736
1737 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001738 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001739 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001740 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001741 }
1742
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001743 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1744 ALOGI("Not sending touch event to %s because it is paused",
1745 newTouchedWindowHandle->getName().c_str());
1746 newTouchedWindowHandle = nullptr;
1747 }
1748
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001749 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001750 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001751 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1752 if (!isResponsive) {
1753 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001754 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1755 newTouchedWindowHandle = nullptr;
1756 }
1757 }
1758
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001759 // Drop events that can't be trusted due to occlusion
1760 if (newTouchedWindowHandle != nullptr &&
1761 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1762 TouchOcclusionInfo occlusionInfo =
1763 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001764 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001765 if (DEBUG_TOUCH_OCCLUSION) {
1766 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1767 for (const auto& log : occlusionInfo.debugInfo) {
1768 ALOGD("%s", log.c_str());
1769 }
1770 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001771 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
1772 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1773 ALOGW("Dropping untrusted touch event due to %s/%d",
1774 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1775 newTouchedWindowHandle = nullptr;
1776 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001777 }
1778 }
1779
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001780 // Also don't send the new touch event to unresponsive gesture monitors
1781 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1782
Michael Wright3dd60e22019-03-27 22:06:44 +00001783 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1784 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001785 "(%d, %d) in display %" PRId32 ".",
1786 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001787 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001788 goto Failed;
1789 }
1790
1791 if (newTouchedWindowHandle != nullptr) {
1792 // Set target flags.
1793 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1794 if (isSplit) {
1795 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001796 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001797 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1798 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1799 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1800 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1801 }
1802
1803 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07001804 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
1805 newHoverWindowHandle = nullptr;
1806 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001807 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00001808 }
1809
1810 // Update the temporary touch state.
1811 BitSet32 pointerIds;
1812 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001813 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001814 pointerIds.markBit(pointerId);
1815 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001816 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001817 }
1818
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001819 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001820 } else {
1821 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1822
1823 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001824 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001825 if (DEBUG_FOCUS) {
1826 ALOGD("Dropping event because the pointer is not down or we previously "
1827 "dropped the pointer down event in display %" PRId32,
1828 displayId);
1829 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001830 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001831 goto Failed;
1832 }
1833
1834 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001835 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001836 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001837 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1838 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001839
1840 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001841 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07001842 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001843 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1844 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001845 if (DEBUG_FOCUS) {
1846 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1847 oldTouchedWindowHandle->getName().c_str(),
1848 newTouchedWindowHandle->getName().c_str(), displayId);
1849 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001850 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001851 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1852 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1853 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001854
1855 // Make a slippery entrance into the new window.
1856 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1857 isSplit = true;
1858 }
1859
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001860 int32_t targetFlags =
1861 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001862 if (isSplit) {
1863 targetFlags |= InputTarget::FLAG_SPLIT;
1864 }
1865 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1866 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1867 }
1868
1869 BitSet32 pointerIds;
1870 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001871 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001872 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001873 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001874 }
1875 }
1876 }
1877
1878 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07001879 // Let the previous window know that the hover sequence is over, unless we already did it
1880 // when dispatching it as is to newTouchedWindowHandle.
1881 if (mLastHoverWindowHandle != nullptr &&
1882 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
1883 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001884#if DEBUG_HOVER
1885 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001886 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001887#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001888 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1889 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001890 }
1891
Garfield Tandf26e862020-07-01 20:18:19 -07001892 // Let the new window know that the hover sequence is starting, unless we already did it
1893 // when dispatching it as is to newTouchedWindowHandle.
1894 if (newHoverWindowHandle != nullptr &&
1895 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
1896 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001897#if DEBUG_HOVER
1898 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001899 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001900#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001901 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1902 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1903 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001904 }
1905 }
1906
1907 // Check permission to inject into all touched foreground windows and ensure there
1908 // is at least one touched foreground window.
1909 {
1910 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001911 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001912 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1913 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001914 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001915 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001916 injectionPermission = INJECTION_PERMISSION_DENIED;
1917 goto Failed;
1918 }
1919 }
1920 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001921 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00001922 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001923 ALOGI("Dropping event because there is no touched foreground window in display "
1924 "%" PRId32 " or gesture monitor to receive it.",
1925 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001926 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001927 goto Failed;
1928 }
1929
1930 // Permission granted to injection into all touched foreground windows.
1931 injectionPermission = INJECTION_PERMISSION_GRANTED;
1932 }
1933
1934 // Check whether windows listening for outside touches are owned by the same UID. If it is
1935 // set the policy flag that we will not reveal coordinate information to this window.
1936 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1937 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001938 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001939 if (foregroundWindowHandle) {
1940 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001941 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001942 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1943 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1944 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001945 tempTouchState.addOrUpdateWindow(inputWindowHandle,
1946 InputTarget::FLAG_ZERO_COORDS,
1947 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001948 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001949 }
1950 }
1951 }
1952 }
1953
Michael Wrightd02c5b62014-02-10 15:10:22 -08001954 // If this is the first pointer going down and the touched window has a wallpaper
1955 // then also add the touched wallpaper windows so they are locked in for the duration
1956 // of the touch gesture.
1957 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1958 // engine only supports touch events. We would need to add a mechanism similar
1959 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1960 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1961 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001962 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001963 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001964 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001965 getWindowHandlesLocked(displayId);
1966 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001967 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001968 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01001969 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001970 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001971 .addOrUpdateWindow(windowHandle,
1972 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1973 InputTarget::
1974 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1975 InputTarget::FLAG_DISPATCH_AS_IS,
1976 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001977 }
1978 }
1979 }
1980 }
1981
1982 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001983 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001984
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001985 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001986 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001987 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001988 }
1989
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001990 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001991 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001992 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00001993 }
1994
Michael Wrightd02c5b62014-02-10 15:10:22 -08001995 // Drop the outside or hover touch windows since we will not care about them
1996 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001997 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001998
1999Failed:
2000 // Check injection permission once and for all.
2001 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002002 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002003 injectionPermission = INJECTION_PERMISSION_GRANTED;
2004 } else {
2005 injectionPermission = INJECTION_PERMISSION_DENIED;
2006 }
2007 }
2008
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002009 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2010 return injectionResult;
2011 }
2012
Michael Wrightd02c5b62014-02-10 15:10:22 -08002013 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002014 if (!wrongDevice) {
2015 if (switchedDevice) {
2016 if (DEBUG_FOCUS) {
2017 ALOGD("Conflicting pointer actions: Switched to a different device.");
2018 }
2019 *outConflictingPointerActions = true;
2020 }
2021
2022 if (isHoverAction) {
2023 // Started hovering, therefore no longer down.
2024 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002025 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002026 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2027 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002028 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002029 *outConflictingPointerActions = true;
2030 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002031 tempTouchState.reset();
2032 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2033 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2034 tempTouchState.deviceId = entry.deviceId;
2035 tempTouchState.source = entry.source;
2036 tempTouchState.displayId = displayId;
2037 }
2038 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2039 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2040 // All pointers up or canceled.
2041 tempTouchState.reset();
2042 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2043 // First pointer went down.
2044 if (oldState && oldState->down) {
2045 if (DEBUG_FOCUS) {
2046 ALOGD("Conflicting pointer actions: Down received while already down.");
2047 }
2048 *outConflictingPointerActions = true;
2049 }
2050 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2051 // One pointer went up.
2052 if (isSplit) {
2053 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2054 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002055
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002056 for (size_t i = 0; i < tempTouchState.windows.size();) {
2057 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2058 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2059 touchedWindow.pointerIds.clearBit(pointerId);
2060 if (touchedWindow.pointerIds.isEmpty()) {
2061 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2062 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002063 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002064 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002065 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002066 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002067 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002068 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002069
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002070 // Save changes unless the action was scroll in which case the temporary touch
2071 // state was only valid for this one action.
2072 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2073 if (tempTouchState.displayId >= 0) {
2074 mTouchStatesByDisplay[displayId] = tempTouchState;
2075 } else {
2076 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002077 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002078 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002079
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002080 // Update hover state.
2081 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002082 }
2083
Michael Wrightd02c5b62014-02-10 15:10:22 -08002084 return injectionResult;
2085}
2086
2087void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002088 int32_t targetFlags, BitSet32 pointerIds,
2089 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002090 std::vector<InputTarget>::iterator it =
2091 std::find_if(inputTargets.begin(), inputTargets.end(),
2092 [&windowHandle](const InputTarget& inputTarget) {
2093 return inputTarget.inputChannel->getConnectionToken() ==
2094 windowHandle->getToken();
2095 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002096
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002097 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002098
2099 if (it == inputTargets.end()) {
2100 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002101 std::shared_ptr<InputChannel> inputChannel =
2102 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002103 if (inputChannel == nullptr) {
2104 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2105 return;
2106 }
2107 inputTarget.inputChannel = inputChannel;
2108 inputTarget.flags = targetFlags;
2109 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2110 inputTargets.push_back(inputTarget);
2111 it = inputTargets.end() - 1;
2112 }
2113
2114 ALOG_ASSERT(it->flags == targetFlags);
2115 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2116
chaviw1ff3d1e2020-07-01 15:53:47 -07002117 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002118}
2119
Michael Wright3dd60e22019-03-27 22:06:44 +00002120void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002121 int32_t displayId, float xOffset,
2122 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002123 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2124 mGlobalMonitorsByDisplay.find(displayId);
2125
2126 if (it != mGlobalMonitorsByDisplay.end()) {
2127 const std::vector<Monitor>& monitors = it->second;
2128 for (const Monitor& monitor : monitors) {
2129 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002130 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002131 }
2132}
2133
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002134void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2135 float yOffset,
2136 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002137 InputTarget target;
2138 target.inputChannel = monitor.inputChannel;
2139 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002140 ui::Transform t;
2141 t.set(xOffset, yOffset);
2142 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002143 inputTargets.push_back(target);
2144}
2145
Michael Wrightd02c5b62014-02-10 15:10:22 -08002146bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002147 const InjectionState* injectionState) {
2148 if (injectionState &&
2149 (windowHandle == nullptr ||
2150 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2151 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002152 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002153 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002154 "owned by uid %d",
2155 injectionState->injectorPid, injectionState->injectorUid,
2156 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002157 } else {
2158 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002159 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002160 }
2161 return false;
2162 }
2163 return true;
2164}
2165
Robert Carrc9bf1d32020-04-13 17:21:08 -07002166/**
2167 * Indicate whether one window handle should be considered as obscuring
2168 * another window handle. We only check a few preconditions. Actually
2169 * checking the bounds is left to the caller.
2170 */
2171static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2172 const sp<InputWindowHandle>& otherHandle) {
2173 // Compare by token so cloned layers aren't counted
2174 if (haveSameToken(windowHandle, otherHandle)) {
2175 return false;
2176 }
2177 auto info = windowHandle->getInfo();
2178 auto otherInfo = otherHandle->getInfo();
2179 if (!otherInfo->visible) {
2180 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002181 } else if (otherInfo->alpha == 0 &&
2182 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2183 // Those act as if they were invisible, so we don't need to flag them.
2184 // We do want to potentially flag touchable windows even if they have 0
2185 // opacity, since they can consume touches and alter the effects of the
2186 // user interaction (eg. apps that rely on
2187 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2188 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2189 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002190 } else if (info->ownerUid == otherInfo->ownerUid) {
2191 // If ownerUid is the same we don't generate occlusion events as there
2192 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002193 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002194 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002195 return false;
2196 } else if (otherInfo->displayId != info->displayId) {
2197 return false;
2198 }
2199 return true;
2200}
2201
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002202/**
2203 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2204 * untrusted, one should check:
2205 *
2206 * 1. If result.hasBlockingOcclusion is true.
2207 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2208 * BLOCK_UNTRUSTED.
2209 *
2210 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2211 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2212 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2213 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2214 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2215 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2216 *
2217 * If neither of those is true, then it means the touch can be allowed.
2218 */
2219InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2220 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002221 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2222 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002223 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2224 TouchOcclusionInfo info;
2225 info.hasBlockingOcclusion = false;
2226 info.obscuringOpacity = 0;
2227 info.obscuringUid = -1;
2228 std::map<int32_t, float> opacityByUid;
2229 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2230 if (windowHandle == otherHandle) {
2231 break; // All future windows are below us. Exit early.
2232 }
2233 const InputWindowInfo* otherInfo = otherHandle->getInfo();
2234 if (canBeObscuredBy(windowHandle, otherHandle) &&
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002235 windowInfo->ownerUid != otherInfo->ownerUid && otherInfo->frameContainsPoint(x, y)) {
2236 if (DEBUG_TOUCH_OCCLUSION) {
2237 info.debugInfo.push_back(
2238 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2239 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002240 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2241 // we perform the checks below to see if the touch can be propagated or not based on the
2242 // window's touch occlusion mode
2243 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2244 info.hasBlockingOcclusion = true;
2245 info.obscuringUid = otherInfo->ownerUid;
2246 info.obscuringPackage = otherInfo->packageName;
2247 break;
2248 }
2249 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2250 uint32_t uid = otherInfo->ownerUid;
2251 float opacity =
2252 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2253 // Given windows A and B:
2254 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2255 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2256 opacityByUid[uid] = opacity;
2257 if (opacity > info.obscuringOpacity) {
2258 info.obscuringOpacity = opacity;
2259 info.obscuringUid = uid;
2260 info.obscuringPackage = otherInfo->packageName;
2261 }
2262 }
2263 }
2264 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002265 if (DEBUG_TOUCH_OCCLUSION) {
2266 info.debugInfo.push_back(
2267 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2268 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002269 return info;
2270}
2271
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002272std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2273 bool isTouchedWindow) const {
2274 return StringPrintf(INDENT2 "* %stype=%s, package=%s/%" PRId32 ", mode=%s, alpha=%.2f, "
2275 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2276 "], window=%s, applicationInfo=%s, flags=%s\n",
2277 (isTouchedWindow) ? "[TOUCHED] " : "",
2278 NamedEnum::string(info->type).c_str(), info->packageName.c_str(),
2279 info->ownerUid, toString(info->touchOcclusionMode).c_str(), info->alpha,
2280 info->frameLeft, info->frameTop, info->frameRight, info->frameBottom,
2281 info->name.c_str(), info->applicationInfo.name.c_str(),
2282 info->flags.string().c_str());
2283}
2284
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002285bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2286 if (occlusionInfo.hasBlockingOcclusion) {
2287 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2288 occlusionInfo.obscuringUid);
2289 return false;
2290 }
2291 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2292 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2293 "%.2f, maximum allowed = %.2f)",
2294 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2295 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2296 return false;
2297 }
2298 return true;
2299}
2300
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002301bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2302 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002303 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002304 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002305 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002306 if (windowHandle == otherHandle) {
2307 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002308 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002309 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002310 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002311 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002312 return true;
2313 }
2314 }
2315 return false;
2316}
2317
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002318bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2319 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002320 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002321 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002322 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002323 if (windowHandle == otherHandle) {
2324 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002325 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002326 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002327 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002328 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002329 return true;
2330 }
2331 }
2332 return false;
2333}
2334
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002335std::string InputDispatcher::getApplicationWindowLabel(
Chris Yea209fde2020-07-22 13:54:51 -07002336 const std::shared_ptr<InputApplicationHandle>& applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002337 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002338 if (applicationHandle != nullptr) {
2339 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002340 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002341 } else {
2342 return applicationHandle->getName();
2343 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002344 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002345 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002346 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002347 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002348 }
2349}
2350
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002351void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002352 if (eventEntry.type == EventEntry::Type::FOCUS) {
2353 // Focus events are passed to apps, but do not represent user activity.
2354 return;
2355 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002356 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002357 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002358 if (focusedWindowHandle != nullptr) {
2359 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002360 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002361#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002362 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002363#endif
2364 return;
2365 }
2366 }
2367
2368 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002369 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002370 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002371 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2372 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002373 return;
2374 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002375
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002376 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002377 eventType = USER_ACTIVITY_EVENT_TOUCH;
2378 }
2379 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002380 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002381 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002382 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2383 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002384 return;
2385 }
2386 eventType = USER_ACTIVITY_EVENT_BUTTON;
2387 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002388 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002389 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002390 case EventEntry::Type::CONFIGURATION_CHANGED:
2391 case EventEntry::Type::DEVICE_RESET: {
2392 LOG_ALWAYS_FATAL("%s events are not user activity",
2393 EventEntry::typeToString(eventEntry.type));
2394 break;
2395 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002396 }
2397
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002398 std::unique_ptr<CommandEntry> commandEntry =
2399 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002400 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002401 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002402 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002403}
2404
2405void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002406 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002407 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002408 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002409 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002410 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002411 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002412 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002413 ATRACE_NAME(message.c_str());
2414 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002415#if DEBUG_DISPATCH_CYCLE
2416 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002417 "globalScaleFactor=%f, pointerIds=0x%x %s",
2418 connection->getInputChannelName().c_str(), inputTarget.flags,
2419 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2420 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002421#endif
2422
2423 // Skip this event if the connection status is not normal.
2424 // We don't want to enqueue additional outbound events if the connection is broken.
2425 if (connection->status != Connection::STATUS_NORMAL) {
2426#if DEBUG_DISPATCH_CYCLE
2427 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002428 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002429#endif
2430 return;
2431 }
2432
2433 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002434 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2435 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2436 "Entry type %s should not have FLAG_SPLIT",
2437 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002438
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002439 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002440 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002441 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002442 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002443 if (!splitMotionEntry) {
2444 return; // split event was dropped
2445 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002446 if (DEBUG_FOCUS) {
2447 ALOGD("channel '%s' ~ Split motion event.",
2448 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002449 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002450 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002451 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2452 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002453 return;
2454 }
2455 }
2456
2457 // Not splitting. Enqueue dispatch entries for the event as is.
2458 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2459}
2460
2461void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002462 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002463 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002464 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002465 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002466 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002467 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002468 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002469 ATRACE_NAME(message.c_str());
2470 }
2471
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002472 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002473
2474 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002475 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002476 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002477 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002478 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002479 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002480 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002481 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002482 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002483 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002484 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002485 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002486 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002487
2488 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002489 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002490 startDispatchCycleLocked(currentTime, connection);
2491 }
2492}
2493
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002494void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002495 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002496 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002497 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002498 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002499 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2500 connection->getInputChannelName().c_str(),
2501 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002502 ATRACE_NAME(message.c_str());
2503 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002504 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002505 if (!(inputTargetFlags & dispatchMode)) {
2506 return;
2507 }
2508 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2509
2510 // This is a new event.
2511 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002512 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002513 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002514
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002515 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2516 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002517 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002518 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002519 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002520 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002521 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002522 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002523 dispatchEntry->resolvedAction = keyEntry.action;
2524 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002525
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002526 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2527 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002528#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002529 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2530 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002531#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002532 return; // skip the inconsistent event
2533 }
2534 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002535 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002536
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002537 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002538 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002539 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2540 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2541 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2542 static_cast<int32_t>(IdGenerator::Source::OTHER);
2543 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002544 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2545 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2546 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2547 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2548 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2549 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2550 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2551 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2552 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2553 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2554 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002555 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002556 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002557 }
2558 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002559 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2560 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002561#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002562 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2563 "event",
2564 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002565#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002566 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2567 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002568
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002569 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002570 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2571 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2572 }
2573 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2574 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2575 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002576
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002577 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2578 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002579#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002580 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2581 "event",
2582 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002583#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002584 return; // skip the inconsistent event
2585 }
2586
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002587 dispatchEntry->resolvedEventId =
2588 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2589 ? mIdGenerator.nextId()
2590 : motionEntry.id;
2591 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2592 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2593 ") to MotionEvent(id=0x%" PRIx32 ").",
2594 motionEntry.id, dispatchEntry->resolvedEventId);
2595 ATRACE_NAME(message.c_str());
2596 }
2597
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002598 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002599 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002600
2601 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002602 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002603 case EventEntry::Type::FOCUS: {
2604 break;
2605 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002606 case EventEntry::Type::CONFIGURATION_CHANGED:
2607 case EventEntry::Type::DEVICE_RESET: {
2608 LOG_ALWAYS_FATAL("%s events should not go to apps",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002609 EventEntry::typeToString(newEntry.type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002610 break;
2611 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002612 }
2613
2614 // Remember that we are waiting for this dispatch to complete.
2615 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002616 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002617 }
2618
2619 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002620 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002621 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002622}
2623
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002624/**
2625 * This function is purely for debugging. It helps us understand where the user interaction
2626 * was taking place. For example, if user is touching launcher, we will see a log that user
2627 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2628 * We will see both launcher and wallpaper in that list.
2629 * Once the interaction with a particular set of connections starts, no new logs will be printed
2630 * until the set of interacted connections changes.
2631 *
2632 * The following items are skipped, to reduce the logspam:
2633 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2634 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2635 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2636 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2637 * Both of those ACTION_UP events would not be logged
2638 * Monitors (both gesture and global): any gesture monitors or global monitors receiving events
2639 * will not be logged. This is omitted to reduce the amount of data printed.
2640 * If you see <none>, it's likely that one of the gesture monitors pilfered the event, and therefore
2641 * gesture monitor is the only connection receiving the remainder of the gesture.
2642 */
2643void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2644 const std::vector<InputTarget>& targets) {
2645 // Skip ACTION_UP events, and all events other than keys and motions
2646 if (entry.type == EventEntry::Type::KEY) {
2647 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2648 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2649 return;
2650 }
2651 } else if (entry.type == EventEntry::Type::MOTION) {
2652 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2653 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2654 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2655 return;
2656 }
2657 } else {
2658 return; // Not a key or a motion
2659 }
2660
2661 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2662 std::vector<sp<Connection>> newConnections;
2663 for (const InputTarget& target : targets) {
2664 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2665 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2666 continue; // Skip windows that receive ACTION_OUTSIDE
2667 }
2668
2669 sp<IBinder> token = target.inputChannel->getConnectionToken();
2670 sp<Connection> connection = getConnectionLocked(token);
2671 if (connection == nullptr || connection->monitor) {
2672 continue; // We only need to keep track of the non-monitor connections.
2673 }
2674 newConnectionTokens.insert(std::move(token));
2675 newConnections.emplace_back(connection);
2676 }
2677 if (newConnectionTokens == mInteractionConnectionTokens) {
2678 return; // no change
2679 }
2680 mInteractionConnectionTokens = newConnectionTokens;
2681
2682 std::string windowList;
2683 for (const sp<Connection>& connection : newConnections) {
2684 windowList += connection->getWindowName() + ", ";
2685 }
2686 std::string message = "Interaction with windows: " + windowList;
2687 if (windowList.empty()) {
2688 message += "<none>";
2689 }
2690 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2691}
2692
chaviwfd6d3512019-03-25 13:23:49 -07002693void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002694 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002695 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002696 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2697 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002698 return;
2699 }
2700
Vishnu Nairad321cd2020-08-20 16:40:21 -07002701 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
2702 if (focusedToken == token) {
2703 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002704 return;
2705 }
2706
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002707 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2708 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002709 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002710 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002711}
2712
2713void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002714 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002715 if (ATRACE_ENABLED()) {
2716 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002717 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002718 ATRACE_NAME(message.c_str());
2719 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002720#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002721 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002722#endif
2723
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002724 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2725 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002726 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002727 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002728 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002729 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002730
2731 // Publish the event.
2732 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002733 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
2734 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002735 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002736 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2737 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002738
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002739 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002740 status = connection->inputPublisher
2741 .publishKeyEvent(dispatchEntry->seq,
2742 dispatchEntry->resolvedEventId, keyEntry.deviceId,
2743 keyEntry.source, keyEntry.displayId,
2744 std::move(hmac), dispatchEntry->resolvedAction,
2745 dispatchEntry->resolvedFlags, keyEntry.keyCode,
2746 keyEntry.scanCode, keyEntry.metaState,
2747 keyEntry.repeatCount, keyEntry.downTime,
2748 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002749 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002750 }
2751
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002752 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002753 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002754
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002755 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002756 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002757
chaviw82357092020-01-28 13:13:06 -08002758 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002759 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002760 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2761 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002762 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002763 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
2764 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002765 // Don't apply window scale here since we don't want scale to affect raw
2766 // coordinates. The scale will be sent back to the client and applied
2767 // later when requesting relative coordinates.
2768 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2769 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002770 }
2771 usingCoords = scaledCoords;
2772 }
2773 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002774 // We don't want the dispatch target to know.
2775 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002776 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002777 scaledCoords[i].clear();
2778 }
2779 usingCoords = scaledCoords;
2780 }
2781 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002782
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002783 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002784
2785 // Publish the motion event.
2786 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002787 .publishMotionEvent(dispatchEntry->seq,
2788 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002789 motionEntry.deviceId, motionEntry.source,
2790 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002791 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002792 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002793 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002794 motionEntry.edgeFlags, motionEntry.metaState,
2795 motionEntry.buttonState,
2796 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07002797 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002798 motionEntry.xPrecision, motionEntry.yPrecision,
2799 motionEntry.xCursorPosition,
2800 motionEntry.yCursorPosition,
2801 motionEntry.downTime, motionEntry.eventTime,
2802 motionEntry.pointerCount,
2803 motionEntry.pointerProperties, usingCoords);
2804 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002805 break;
2806 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002807 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002808 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002809 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002810 focusEntry.id,
2811 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002812 mInTouchMode);
2813 break;
2814 }
2815
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002816 case EventEntry::Type::CONFIGURATION_CHANGED:
2817 case EventEntry::Type::DEVICE_RESET: {
2818 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002819 EventEntry::typeToString(eventEntry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002820 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002821 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002822 }
2823
2824 // Check the result.
2825 if (status) {
2826 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002827 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002828 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002829 "This is unexpected because the wait queue is empty, so the pipe "
2830 "should be empty and we shouldn't have any problems writing an "
2831 "event to it, status=%d",
2832 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002833 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2834 } else {
2835 // Pipe is full and we are waiting for the app to finish process some events
2836 // before sending more events to it.
2837#if DEBUG_DISPATCH_CYCLE
2838 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002839 "waiting for the application to catch up",
2840 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002841#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08002842 }
2843 } else {
2844 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002845 "status=%d",
2846 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002847 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2848 }
2849 return;
2850 }
2851
2852 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002853 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2854 connection->outboundQueue.end(),
2855 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002856 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002857 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002858 if (connection->responsive) {
2859 mAnrTracker.insert(dispatchEntry->timeoutTime,
2860 connection->inputChannel->getConnectionToken());
2861 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002862 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002863 }
2864}
2865
chaviw09c8d2d2020-08-24 15:48:26 -07002866std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
2867 size_t size;
2868 switch (event.type) {
2869 case VerifiedInputEvent::Type::KEY: {
2870 size = sizeof(VerifiedKeyEvent);
2871 break;
2872 }
2873 case VerifiedInputEvent::Type::MOTION: {
2874 size = sizeof(VerifiedMotionEvent);
2875 break;
2876 }
2877 }
2878 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
2879 return mHmacKeyManager.sign(start, size);
2880}
2881
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002882const std::array<uint8_t, 32> InputDispatcher::getSignature(
2883 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
2884 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
2885 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
2886 // Only sign events up and down events as the purely move events
2887 // are tied to their up/down counterparts so signing would be redundant.
2888 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
2889 verifiedEvent.actionMasked = actionMasked;
2890 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07002891 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002892 }
2893 return INVALID_HMAC;
2894}
2895
2896const std::array<uint8_t, 32> InputDispatcher::getSignature(
2897 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
2898 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
2899 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
2900 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07002901 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002902}
2903
Michael Wrightd02c5b62014-02-10 15:10:22 -08002904void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002905 const sp<Connection>& connection, uint32_t seq,
2906 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002907#if DEBUG_DISPATCH_CYCLE
2908 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002909 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002910#endif
2911
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002912 if (connection->status == Connection::STATUS_BROKEN ||
2913 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002914 return;
2915 }
2916
2917 // Notify other system components and prepare to start the next dispatch cycle.
2918 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2919}
2920
2921void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002922 const sp<Connection>& connection,
2923 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924#if DEBUG_DISPATCH_CYCLE
2925 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002926 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002927#endif
2928
2929 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002930 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002931 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002932 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002933 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002934
2935 // The connection appears to be unrecoverably broken.
2936 // Ignore already broken or zombie connections.
2937 if (connection->status == Connection::STATUS_NORMAL) {
2938 connection->status = Connection::STATUS_BROKEN;
2939
2940 if (notify) {
2941 // Notify other system components.
2942 onDispatchCycleBrokenLocked(currentTime, connection);
2943 }
2944 }
2945}
2946
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002947void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2948 while (!queue.empty()) {
2949 DispatchEntry* dispatchEntry = queue.front();
2950 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002951 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002952 }
2953}
2954
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002955void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002956 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002957 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002958 }
2959 delete dispatchEntry;
2960}
2961
2962int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2963 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2964
2965 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002966 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002967
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002968 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002969 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002970 "fd=%d, events=0x%x",
2971 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002972 return 0; // remove the callback
2973 }
2974
2975 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002976 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002977 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2978 if (!(events & ALOOPER_EVENT_INPUT)) {
2979 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002980 "events=0x%x",
2981 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002982 return 1;
2983 }
2984
2985 nsecs_t currentTime = now();
2986 bool gotOne = false;
2987 status_t status;
2988 for (;;) {
2989 uint32_t seq;
2990 bool handled;
2991 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2992 if (status) {
2993 break;
2994 }
2995 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2996 gotOne = true;
2997 }
2998 if (gotOne) {
2999 d->runCommandsLockedInterruptible();
3000 if (status == WOULD_BLOCK) {
3001 return 1;
3002 }
3003 }
3004
3005 notify = status != DEAD_OBJECT || !connection->monitor;
3006 if (notify) {
3007 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003008 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003009 }
3010 } else {
3011 // Monitor channels are never explicitly unregistered.
3012 // We do it automatically when the remote endpoint is closed so don't warn
3013 // about them.
arthurhungd352cb32020-04-28 17:09:28 +08003014 const bool stillHaveWindowHandle =
3015 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3016 nullptr;
3017 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003018 if (notify) {
3019 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003020 "events=0x%x",
3021 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003022 }
3023 }
3024
Garfield Tan15601662020-09-22 15:32:38 -07003025 // Remove the channel.
3026 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003027 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003028 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003029}
3030
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003031void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003032 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003033 for (const auto& pair : mConnectionsByFd) {
3034 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003035 }
3036}
3037
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003038void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003039 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003040 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3041 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3042}
3043
3044void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3045 const CancelationOptions& options,
3046 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3047 for (const auto& it : monitorsByDisplay) {
3048 const std::vector<Monitor>& monitors = it.second;
3049 for (const Monitor& monitor : monitors) {
3050 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003051 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003052 }
3053}
3054
Michael Wrightd02c5b62014-02-10 15:10:22 -08003055void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003056 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003057 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003058 if (connection == nullptr) {
3059 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003060 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003061
3062 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003063}
3064
3065void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3066 const sp<Connection>& connection, const CancelationOptions& options) {
3067 if (connection->status == Connection::STATUS_BROKEN) {
3068 return;
3069 }
3070
3071 nsecs_t currentTime = now();
3072
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003073 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003074 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003075
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003076 if (cancelationEvents.empty()) {
3077 return;
3078 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003079#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003080 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3081 "with reality: %s, mode=%d.",
3082 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3083 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003084#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003085
3086 InputTarget target;
3087 sp<InputWindowHandle> windowHandle =
3088 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3089 if (windowHandle != nullptr) {
3090 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003091 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003092 target.globalScaleFactor = windowInfo->globalScaleFactor;
3093 }
3094 target.inputChannel = connection->inputChannel;
3095 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3096
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003097 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003098 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003099 switch (cancelationEventEntry->type) {
3100 case EventEntry::Type::KEY: {
3101 logOutboundKeyDetails("cancel - ",
3102 static_cast<const KeyEntry&>(*cancelationEventEntry));
3103 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003104 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003105 case EventEntry::Type::MOTION: {
3106 logOutboundMotionDetails("cancel - ",
3107 static_cast<const MotionEntry&>(*cancelationEventEntry));
3108 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003109 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003110 case EventEntry::Type::FOCUS: {
3111 LOG_ALWAYS_FATAL("Canceling focus events is not supported");
3112 break;
3113 }
3114 case EventEntry::Type::CONFIGURATION_CHANGED:
3115 case EventEntry::Type::DEVICE_RESET: {
3116 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3117 EventEntry::typeToString(cancelationEventEntry->type));
3118 break;
3119 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003120 }
3121
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003122 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3123 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003124 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003125
3126 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003127}
3128
Svet Ganov5d3bc372020-01-26 23:11:07 -08003129void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3130 const sp<Connection>& connection) {
3131 if (connection->status == Connection::STATUS_BROKEN) {
3132 return;
3133 }
3134
3135 nsecs_t currentTime = now();
3136
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003137 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003138 connection->inputState.synthesizePointerDownEvents(currentTime);
3139
3140 if (downEvents.empty()) {
3141 return;
3142 }
3143
3144#if DEBUG_OUTBOUND_EVENT_DETAILS
3145 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3146 connection->getInputChannelName().c_str(), downEvents.size());
3147#endif
3148
3149 InputTarget target;
3150 sp<InputWindowHandle> windowHandle =
3151 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3152 if (windowHandle != nullptr) {
3153 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003154 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003155 target.globalScaleFactor = windowInfo->globalScaleFactor;
3156 }
3157 target.inputChannel = connection->inputChannel;
3158 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3159
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003160 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003161 switch (downEventEntry->type) {
3162 case EventEntry::Type::MOTION: {
3163 logOutboundMotionDetails("down - ",
3164 static_cast<const MotionEntry&>(*downEventEntry));
3165 break;
3166 }
3167
3168 case EventEntry::Type::KEY:
3169 case EventEntry::Type::FOCUS:
3170 case EventEntry::Type::CONFIGURATION_CHANGED:
3171 case EventEntry::Type::DEVICE_RESET: {
3172 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3173 EventEntry::typeToString(downEventEntry->type));
3174 break;
3175 }
3176 }
3177
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003178 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3179 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003180 }
3181
3182 startDispatchCycleLocked(currentTime, connection);
3183}
3184
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003185std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3186 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003187 ALOG_ASSERT(pointerIds.value != 0);
3188
3189 uint32_t splitPointerIndexMap[MAX_POINTERS];
3190 PointerProperties splitPointerProperties[MAX_POINTERS];
3191 PointerCoords splitPointerCoords[MAX_POINTERS];
3192
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003193 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003194 uint32_t splitPointerCount = 0;
3195
3196 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003197 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003198 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003199 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003200 uint32_t pointerId = uint32_t(pointerProperties.id);
3201 if (pointerIds.hasBit(pointerId)) {
3202 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3203 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3204 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003205 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003206 splitPointerCount += 1;
3207 }
3208 }
3209
3210 if (splitPointerCount != pointerIds.count()) {
3211 // This is bad. We are missing some of the pointers that we expected to deliver.
3212 // Most likely this indicates that we received an ACTION_MOVE events that has
3213 // different pointer ids than we expected based on the previous ACTION_DOWN
3214 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3215 // in this way.
3216 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003217 "we expected there to be %d pointers. This probably means we received "
3218 "a broken sequence of pointer ids from the input device.",
3219 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003220 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003221 }
3222
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003223 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003224 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003225 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3226 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003227 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3228 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003229 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003230 uint32_t pointerId = uint32_t(pointerProperties.id);
3231 if (pointerIds.hasBit(pointerId)) {
3232 if (pointerIds.count() == 1) {
3233 // The first/last pointer went down/up.
3234 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003235 ? AMOTION_EVENT_ACTION_DOWN
3236 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003237 } else {
3238 // A secondary pointer went down/up.
3239 uint32_t splitPointerIndex = 0;
3240 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3241 splitPointerIndex += 1;
3242 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003243 action = maskedAction |
3244 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003245 }
3246 } else {
3247 // An unrelated pointer changed.
3248 action = AMOTION_EVENT_ACTION_MOVE;
3249 }
3250 }
3251
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003252 int32_t newId = mIdGenerator.nextId();
3253 if (ATRACE_ENABLED()) {
3254 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3255 ") to MotionEvent(id=0x%" PRIx32 ").",
3256 originalMotionEntry.id, newId);
3257 ATRACE_NAME(message.c_str());
3258 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003259 std::unique_ptr<MotionEntry> splitMotionEntry =
3260 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3261 originalMotionEntry.deviceId, originalMotionEntry.source,
3262 originalMotionEntry.displayId,
3263 originalMotionEntry.policyFlags, action,
3264 originalMotionEntry.actionButton,
3265 originalMotionEntry.flags, originalMotionEntry.metaState,
3266 originalMotionEntry.buttonState,
3267 originalMotionEntry.classification,
3268 originalMotionEntry.edgeFlags,
3269 originalMotionEntry.xPrecision,
3270 originalMotionEntry.yPrecision,
3271 originalMotionEntry.xCursorPosition,
3272 originalMotionEntry.yCursorPosition,
3273 originalMotionEntry.downTime, splitPointerCount,
3274 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003275
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003276 if (originalMotionEntry.injectionState) {
3277 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003278 splitMotionEntry->injectionState->refCount += 1;
3279 }
3280
3281 return splitMotionEntry;
3282}
3283
3284void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3285#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003286 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003287#endif
3288
3289 bool needWake;
3290 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003291 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003292
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003293 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3294 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3295 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003296 } // release lock
3297
3298 if (needWake) {
3299 mLooper->wake();
3300 }
3301}
3302
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003303/**
3304 * If one of the meta shortcuts is detected, process them here:
3305 * Meta + Backspace -> generate BACK
3306 * Meta + Enter -> generate HOME
3307 * This will potentially overwrite keyCode and metaState.
3308 */
3309void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003310 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003311 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3312 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3313 if (keyCode == AKEYCODE_DEL) {
3314 newKeyCode = AKEYCODE_BACK;
3315 } else if (keyCode == AKEYCODE_ENTER) {
3316 newKeyCode = AKEYCODE_HOME;
3317 }
3318 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003319 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003320 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003321 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003322 keyCode = newKeyCode;
3323 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3324 }
3325 } else if (action == AKEY_EVENT_ACTION_UP) {
3326 // In order to maintain a consistent stream of up and down events, check to see if the key
3327 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3328 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003329 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003330 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003331 auto replacementIt = mReplacedKeys.find(replacement);
3332 if (replacementIt != mReplacedKeys.end()) {
3333 keyCode = replacementIt->second;
3334 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003335 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3336 }
3337 }
3338}
3339
Michael Wrightd02c5b62014-02-10 15:10:22 -08003340void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3341#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003342 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3343 "policyFlags=0x%x, action=0x%x, "
3344 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3345 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3346 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3347 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003348#endif
3349 if (!validateKeyEvent(args->action)) {
3350 return;
3351 }
3352
3353 uint32_t policyFlags = args->policyFlags;
3354 int32_t flags = args->flags;
3355 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003356 // InputDispatcher tracks and generates key repeats on behalf of
3357 // whatever notifies it, so repeatCount should always be set to 0
3358 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003359 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3360 policyFlags |= POLICY_FLAG_VIRTUAL;
3361 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3362 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003363 if (policyFlags & POLICY_FLAG_FUNCTION) {
3364 metaState |= AMETA_FUNCTION_ON;
3365 }
3366
3367 policyFlags |= POLICY_FLAG_TRUSTED;
3368
Michael Wright78f24442014-08-06 15:55:28 -07003369 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003370 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003371
Michael Wrightd02c5b62014-02-10 15:10:22 -08003372 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003373 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003374 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3375 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003376
Michael Wright2b3c3302018-03-02 17:19:13 +00003377 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003378 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003379 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3380 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003381 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003382 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003383
Michael Wrightd02c5b62014-02-10 15:10:22 -08003384 bool needWake;
3385 { // acquire lock
3386 mLock.lock();
3387
3388 if (shouldSendKeyToInputFilterLocked(args)) {
3389 mLock.unlock();
3390
3391 policyFlags |= POLICY_FLAG_FILTERED;
3392 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3393 return; // event was consumed by the filter
3394 }
3395
3396 mLock.lock();
3397 }
3398
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003399 std::unique_ptr<KeyEntry> newEntry =
3400 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3401 args->displayId, policyFlags, args->action, flags,
3402 keyCode, args->scanCode, metaState, repeatCount,
3403 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003404
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003405 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003406 mLock.unlock();
3407 } // release lock
3408
3409 if (needWake) {
3410 mLooper->wake();
3411 }
3412}
3413
3414bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3415 return mInputFilterEnabled;
3416}
3417
3418void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3419#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003420 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3421 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003422 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3423 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003424 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003425 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3426 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3427 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3428 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003429 for (uint32_t i = 0; i < args->pointerCount; i++) {
3430 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003431 "x=%f, y=%f, pressure=%f, size=%f, "
3432 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3433 "orientation=%f",
3434 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3435 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3436 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3437 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3438 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3439 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3440 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3441 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3442 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3443 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003444 }
3445#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003446 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3447 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003448 return;
3449 }
3450
3451 uint32_t policyFlags = args->policyFlags;
3452 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003453
3454 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003455 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003456 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3457 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003458 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003459 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003460
3461 bool needWake;
3462 { // acquire lock
3463 mLock.lock();
3464
3465 if (shouldSendMotionToInputFilterLocked(args)) {
3466 mLock.unlock();
3467
3468 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003469 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003470 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3471 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003472 args->metaState, args->buttonState, args->classification, transform,
3473 args->xPrecision, args->yPrecision, args->xCursorPosition,
3474 args->yCursorPosition, args->downTime, args->eventTime,
3475 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003476
3477 policyFlags |= POLICY_FLAG_FILTERED;
3478 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3479 return; // event was consumed by the filter
3480 }
3481
3482 mLock.lock();
3483 }
3484
3485 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003486 std::unique_ptr<MotionEntry> newEntry =
3487 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3488 args->source, args->displayId, policyFlags,
3489 args->action, args->actionButton, args->flags,
3490 args->metaState, args->buttonState,
3491 args->classification, args->edgeFlags,
3492 args->xPrecision, args->yPrecision,
3493 args->xCursorPosition, args->yCursorPosition,
3494 args->downTime, args->pointerCount,
3495 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003496
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003497 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003498 mLock.unlock();
3499 } // release lock
3500
3501 if (needWake) {
3502 mLooper->wake();
3503 }
3504}
3505
3506bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003507 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003508}
3509
3510void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3511#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003512 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003513 "switchMask=0x%08x",
3514 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003515#endif
3516
3517 uint32_t policyFlags = args->policyFlags;
3518 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003519 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003520}
3521
3522void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3523#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003524 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3525 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003526#endif
3527
3528 bool needWake;
3529 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003530 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003531
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003532 std::unique_ptr<DeviceResetEntry> newEntry =
3533 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3534 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003535 } // release lock
3536
3537 if (needWake) {
3538 mLooper->wake();
3539 }
3540}
3541
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003542InputEventInjectionResult InputDispatcher::injectInputEvent(
3543 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3544 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003545#if DEBUG_INBOUND_EVENT_DETAILS
3546 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003547 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3548 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003549#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003550 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003551
3552 policyFlags |= POLICY_FLAG_INJECTED;
3553 if (hasInjectionPermission(injectorPid, injectorUid)) {
3554 policyFlags |= POLICY_FLAG_TRUSTED;
3555 }
3556
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003557 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003558 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003559 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003560 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3561 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003562 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003563 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003564 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003565
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003566 int32_t flags = incomingKey.getFlags();
3567 int32_t keyCode = incomingKey.getKeyCode();
3568 int32_t metaState = incomingKey.getMetaState();
3569 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003570 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003571 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003572 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003573 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3574 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3575 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003576
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003577 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3578 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003579 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003580
3581 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3582 android::base::Timer t;
3583 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3584 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3585 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3586 std::to_string(t.duration().count()).c_str());
3587 }
3588 }
3589
3590 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003591 std::unique_ptr<KeyEntry> injectedEntry =
3592 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3593 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3594 incomingKey.getDisplayId(), policyFlags, action,
3595 flags, keyCode, incomingKey.getScanCode(), metaState,
3596 incomingKey.getRepeatCount(),
3597 incomingKey.getDownTime());
3598 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003599 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003600 }
3601
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003602 case AINPUT_EVENT_TYPE_MOTION: {
3603 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3604 int32_t action = motionEvent->getAction();
3605 size_t pointerCount = motionEvent->getPointerCount();
3606 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3607 int32_t actionButton = motionEvent->getActionButton();
3608 int32_t displayId = motionEvent->getDisplayId();
3609 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003610 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003611 }
3612
3613 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3614 nsecs_t eventTime = motionEvent->getEventTime();
3615 android::base::Timer t;
3616 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3617 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3618 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3619 std::to_string(t.duration().count()).c_str());
3620 }
3621 }
3622
3623 mLock.lock();
3624 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3625 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003626 std::unique_ptr<MotionEntry> injectedEntry =
3627 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3628 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3629 motionEvent->getDisplayId(), policyFlags, action,
3630 actionButton, motionEvent->getFlags(),
3631 motionEvent->getMetaState(),
3632 motionEvent->getButtonState(),
3633 motionEvent->getClassification(),
3634 motionEvent->getEdgeFlags(),
3635 motionEvent->getXPrecision(),
3636 motionEvent->getYPrecision(),
3637 motionEvent->getRawXCursorPosition(),
3638 motionEvent->getRawYCursorPosition(),
3639 motionEvent->getDownTime(),
3640 uint32_t(pointerCount), pointerProperties,
3641 samplePointerCoords, motionEvent->getXOffset(),
3642 motionEvent->getYOffset());
3643 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003644 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3645 sampleEventTimes += 1;
3646 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003647 std::unique_ptr<MotionEntry> nextInjectedEntry =
3648 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3649 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3650 motionEvent->getDisplayId(), policyFlags,
3651 action, actionButton, motionEvent->getFlags(),
3652 motionEvent->getMetaState(),
3653 motionEvent->getButtonState(),
3654 motionEvent->getClassification(),
3655 motionEvent->getEdgeFlags(),
3656 motionEvent->getXPrecision(),
3657 motionEvent->getYPrecision(),
3658 motionEvent->getRawXCursorPosition(),
3659 motionEvent->getRawYCursorPosition(),
3660 motionEvent->getDownTime(),
3661 uint32_t(pointerCount), pointerProperties,
3662 samplePointerCoords,
3663 motionEvent->getXOffset(),
3664 motionEvent->getYOffset());
3665 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003666 }
3667 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003668 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003669
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003670 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003671 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003672 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003673 }
3674
3675 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003676 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003677 injectionState->injectionIsAsync = true;
3678 }
3679
3680 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003681 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003682
3683 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003684 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003685 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003686 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003687 }
3688
3689 mLock.unlock();
3690
3691 if (needWake) {
3692 mLooper->wake();
3693 }
3694
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003695 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003696 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003697 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003698
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003699 if (syncMode == InputEventInjectionSync::NONE) {
3700 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003701 } else {
3702 for (;;) {
3703 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003704 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003705 break;
3706 }
3707
3708 nsecs_t remainingTimeout = endTime - now();
3709 if (remainingTimeout <= 0) {
3710#if DEBUG_INJECTION
3711 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003712 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003713#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003714 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003715 break;
3716 }
3717
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003718 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003719 }
3720
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003721 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3722 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003723 while (injectionState->pendingForegroundDispatches != 0) {
3724#if DEBUG_INJECTION
3725 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003726 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003727#endif
3728 nsecs_t remainingTimeout = endTime - now();
3729 if (remainingTimeout <= 0) {
3730#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003731 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3732 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003733#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003734 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003735 break;
3736 }
3737
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003738 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003739 }
3740 }
3741 }
3742
3743 injectionState->release();
3744 } // release lock
3745
3746#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003747 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003748 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003749#endif
3750
3751 return injectionResult;
3752}
3753
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003754std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05003755 std::array<uint8_t, 32> calculatedHmac;
3756 std::unique_ptr<VerifiedInputEvent> result;
3757 switch (event.getType()) {
3758 case AINPUT_EVENT_TYPE_KEY: {
3759 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
3760 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
3761 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003762 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05003763 break;
3764 }
3765 case AINPUT_EVENT_TYPE_MOTION: {
3766 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
3767 VerifiedMotionEvent verifiedMotionEvent =
3768 verifiedMotionEventFromMotionEvent(motionEvent);
3769 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003770 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05003771 break;
3772 }
3773 default: {
3774 ALOGE("Cannot verify events of type %" PRId32, event.getType());
3775 return nullptr;
3776 }
3777 }
3778 if (calculatedHmac == INVALID_HMAC) {
3779 return nullptr;
3780 }
3781 if (calculatedHmac != event.getHmac()) {
3782 return nullptr;
3783 }
3784 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003785}
3786
Michael Wrightd02c5b62014-02-10 15:10:22 -08003787bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003788 return injectorUid == 0 ||
3789 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003790}
3791
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003792void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003793 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003794 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003795 if (injectionState) {
3796#if DEBUG_INJECTION
3797 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003798 "injectorPid=%d, injectorUid=%d",
3799 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003800#endif
3801
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003802 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003803 // Log the outcome since the injector did not wait for the injection result.
3804 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003805 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003806 ALOGV("Asynchronous input event injection succeeded.");
3807 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003808 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003809 ALOGW("Asynchronous input event injection failed.");
3810 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003811 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003812 ALOGW("Asynchronous input event injection permission denied.");
3813 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003814 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003815 ALOGW("Asynchronous input event injection timed out.");
3816 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003817 case InputEventInjectionResult::PENDING:
3818 ALOGE("Setting result to 'PENDING' for asynchronous injection");
3819 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003820 }
3821 }
3822
3823 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003824 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003825 }
3826}
3827
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003828void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
3829 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003830 if (injectionState) {
3831 injectionState->pendingForegroundDispatches += 1;
3832 }
3833}
3834
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003835void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
3836 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003837 if (injectionState) {
3838 injectionState->pendingForegroundDispatches -= 1;
3839
3840 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003841 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003842 }
3843 }
3844}
3845
Vishnu Nairad321cd2020-08-20 16:40:21 -07003846const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003847 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003848 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
3849 auto it = mWindowHandlesByDisplay.find(displayId);
3850 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08003851}
3852
Michael Wrightd02c5b62014-02-10 15:10:22 -08003853sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003854 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08003855 if (windowHandleToken == nullptr) {
3856 return nullptr;
3857 }
3858
Arthur Hungb92218b2018-08-14 12:00:21 +08003859 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003860 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003861 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003862 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003863 return windowHandle;
3864 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865 }
3866 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003867 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003868}
3869
Vishnu Nairad321cd2020-08-20 16:40:21 -07003870sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
3871 int displayId) const {
3872 if (windowHandleToken == nullptr) {
3873 return nullptr;
3874 }
3875
3876 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3877 if (windowHandle->getToken() == windowHandleToken) {
3878 return windowHandle;
3879 }
3880 }
3881 return nullptr;
3882}
3883
3884sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
3885 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
3886 return getWindowHandleLocked(focusedToken, displayId);
3887}
3888
Mady Mellor017bcd12020-06-23 19:12:00 +00003889bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
3890 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003891 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00003892 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08003893 if (handle->getId() == windowHandle->getId() &&
3894 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00003895 if (windowHandle->getInfo()->displayId != it.first) {
3896 ALOGE("Found window %s in display %" PRId32
3897 ", but it should belong to display %" PRId32,
3898 windowHandle->getName().c_str(), it.first,
3899 windowHandle->getInfo()->displayId);
3900 }
3901 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08003902 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003903 }
3904 }
3905 return false;
3906}
3907
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05003908bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
3909 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
3910 const bool noInputChannel =
3911 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3912 if (connection != nullptr && noInputChannel) {
3913 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
3914 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
3915 return false;
3916 }
3917
3918 if (connection == nullptr) {
3919 if (!noInputChannel) {
3920 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
3921 }
3922 return false;
3923 }
3924 if (!connection->responsive) {
3925 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
3926 return false;
3927 }
3928 return true;
3929}
3930
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003931std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
3932 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07003933 size_t count = mInputChannelsByToken.count(token);
3934 if (count == 0) {
3935 return nullptr;
3936 }
3937 return mInputChannelsByToken.at(token);
3938}
3939
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003940void InputDispatcher::updateWindowHandlesForDisplayLocked(
3941 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3942 if (inputWindowHandles.empty()) {
3943 // Remove all handles on a display if there are no windows left.
3944 mWindowHandlesByDisplay.erase(displayId);
3945 return;
3946 }
3947
3948 // Since we compare the pointer of input window handles across window updates, we need
3949 // to make sure the handle object for the same window stays unchanged across updates.
3950 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07003951 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003952 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07003953 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003954 }
3955
3956 std::vector<sp<InputWindowHandle>> newHandles;
3957 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3958 if (!handle->updateInfo()) {
3959 // handle no longer valid
3960 continue;
3961 }
3962
3963 const InputWindowInfo* info = handle->getInfo();
3964 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3965 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3966 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01003967 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3968 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
3969 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003970 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07003971 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003972 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07003973 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003974 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003975 }
3976
3977 if (info->displayId != displayId) {
3978 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3979 handle->getName().c_str(), displayId, info->displayId);
3980 continue;
3981 }
3982
Robert Carredd13602020-04-13 17:24:34 -07003983 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
3984 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07003985 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003986 oldHandle->updateFrom(handle);
3987 newHandles.push_back(oldHandle);
3988 } else {
3989 newHandles.push_back(handle);
3990 }
3991 }
3992
3993 // Insert or replace
3994 mWindowHandlesByDisplay[displayId] = newHandles;
3995}
3996
Arthur Hung72d8dc32020-03-28 00:48:39 +00003997void InputDispatcher::setInputWindows(
3998 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
3999 { // acquire lock
4000 std::scoped_lock _l(mLock);
4001 for (auto const& i : handlesPerDisplay) {
4002 setInputWindowsLocked(i.second, i.first);
4003 }
4004 }
4005 // Wake up poll loop since it may need to make new input dispatching choices.
4006 mLooper->wake();
4007}
4008
Arthur Hungb92218b2018-08-14 12:00:21 +08004009/**
4010 * Called from InputManagerService, update window handle list by displayId that can receive input.
4011 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4012 * If set an empty list, remove all handles from the specific display.
4013 * For focused handle, check if need to change and send a cancel event to previous one.
4014 * For removed handle, check if need to send a cancel event if already in touch.
4015 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004016void InputDispatcher::setInputWindowsLocked(
4017 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004018 if (DEBUG_FOCUS) {
4019 std::string windowList;
4020 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4021 windowList += iwh->getName() + " ";
4022 }
4023 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4024 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004025
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004026 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4027 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4028 const bool noInputWindow =
4029 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4030 if (noInputWindow && window->getToken() != nullptr) {
4031 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4032 window->getName().c_str());
4033 window->releaseChannel();
4034 }
4035 }
4036
Arthur Hung72d8dc32020-03-28 00:48:39 +00004037 // Copy old handles for release if they are no longer present.
4038 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004039
Arthur Hung72d8dc32020-03-28 00:48:39 +00004040 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004041
Vishnu Nair958da932020-08-21 17:12:37 -07004042 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4043 if (mLastHoverWindowHandle &&
4044 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4045 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004046 mLastHoverWindowHandle = nullptr;
4047 }
4048
Vishnu Nair958da932020-08-21 17:12:37 -07004049 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4050 if (focusedToken) {
4051 FocusResult result = checkTokenFocusableLocked(focusedToken, displayId);
4052 if (result != FocusResult::OK) {
4053 onFocusChangedLocked(focusedToken, nullptr, displayId, typeToString(result));
4054 }
4055 }
4056
4057 std::optional<FocusRequest> focusRequest =
4058 getOptionalValueByKey(mPendingFocusRequests, displayId);
4059 if (focusRequest) {
4060 // If the window from the pending request is now visible, provide it focus.
4061 FocusResult result = handleFocusRequestLocked(*focusRequest);
4062 if (result != FocusResult::NOT_VISIBLE) {
4063 // Drop the request if we were able to change the focus or we cannot change
4064 // it for another reason.
4065 mPendingFocusRequests.erase(displayId);
4066 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004067 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004068
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004069 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4070 mTouchStatesByDisplay.find(displayId);
4071 if (stateIt != mTouchStatesByDisplay.end()) {
4072 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004073 for (size_t i = 0; i < state.windows.size();) {
4074 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004075 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004076 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004077 ALOGD("Touched window was removed: %s in display %" PRId32,
4078 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004079 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004080 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004081 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4082 if (touchedInputChannel != nullptr) {
4083 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4084 "touched window was removed");
4085 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004086 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004087 state.windows.erase(state.windows.begin() + i);
4088 } else {
4089 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004090 }
4091 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004092 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004093
Arthur Hung72d8dc32020-03-28 00:48:39 +00004094 // Release information for windows that are no longer present.
4095 // This ensures that unused input channels are released promptly.
4096 // Otherwise, they might stick around until the window handle is destroyed
4097 // which might not happen until the next GC.
4098 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004099 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004100 if (DEBUG_FOCUS) {
4101 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004102 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004103 oldWindowHandle->releaseChannel();
Arthur Hung25e2af12020-03-26 12:58:37 +00004104 }
chaviw291d88a2019-02-14 10:33:58 -08004105 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004106}
4107
4108void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004109 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004110 if (DEBUG_FOCUS) {
4111 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4112 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4113 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004114 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004115 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004116
Chris Yea209fde2020-07-22 13:54:51 -07004117 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004118 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004119
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004120 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4121 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004122 }
4123
Chris Yea209fde2020-07-22 13:54:51 -07004124 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004125 if (inputApplicationHandle != nullptr) {
4126 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4127 } else {
4128 mFocusedApplicationHandlesByDisplay.erase(displayId);
4129 }
4130
4131 // No matter what the old focused application was, stop waiting on it because it is
4132 // no longer focused.
4133 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004134 } // release lock
4135
4136 // Wake up poll loop since it may need to make new input dispatching choices.
4137 mLooper->wake();
4138}
4139
Tiger Huang721e26f2018-07-24 22:26:19 +08004140/**
4141 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4142 * the display not specified.
4143 *
4144 * We track any unreleased events for each window. If a window loses the ability to receive the
4145 * released event, we will send a cancel event to it. So when the focused display is changed, we
4146 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4147 * display. The display-specified events won't be affected.
4148 */
4149void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004150 if (DEBUG_FOCUS) {
4151 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4152 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004153 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004154 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004155
4156 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004157 sp<IBinder> oldFocusedWindowToken =
4158 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4159 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004160 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004161 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004162 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004163 CancelationOptions
4164 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4165 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004166 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004167 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4168 }
4169 }
4170 mFocusedDisplayId = displayId;
4171
Chris Ye3c2d6f52020-08-09 10:39:48 -07004172 // Find new focused window and validate
Vishnu Nairad321cd2020-08-20 16:40:21 -07004173 sp<IBinder> newFocusedWindowToken =
4174 getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4175 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004176
Vishnu Nairad321cd2020-08-20 16:40:21 -07004177 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004178 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004179 if (!mFocusedWindowTokenByDisplay.empty()) {
4180 ALOGE("But another display has a focused window\n%s",
4181 dumpFocusedWindowsLocked().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004182 }
4183 }
4184 }
4185
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004186 if (DEBUG_FOCUS) {
4187 logDispatchStateLocked();
4188 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004189 } // release lock
4190
4191 // Wake up poll loop since it may need to make new input dispatching choices.
4192 mLooper->wake();
4193}
4194
Michael Wrightd02c5b62014-02-10 15:10:22 -08004195void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004196 if (DEBUG_FOCUS) {
4197 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4198 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004199
4200 bool changed;
4201 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004202 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004203
4204 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4205 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004206 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004207 }
4208
4209 if (mDispatchEnabled && !enabled) {
4210 resetAndDropEverythingLocked("dispatcher is being disabled");
4211 }
4212
4213 mDispatchEnabled = enabled;
4214 mDispatchFrozen = frozen;
4215 changed = true;
4216 } else {
4217 changed = false;
4218 }
4219
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004220 if (DEBUG_FOCUS) {
4221 logDispatchStateLocked();
4222 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004223 } // release lock
4224
4225 if (changed) {
4226 // Wake up poll loop since it may need to make new input dispatching choices.
4227 mLooper->wake();
4228 }
4229}
4230
4231void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004232 if (DEBUG_FOCUS) {
4233 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4234 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004235
4236 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004237 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004238
4239 if (mInputFilterEnabled == enabled) {
4240 return;
4241 }
4242
4243 mInputFilterEnabled = enabled;
4244 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4245 } // release lock
4246
4247 // Wake up poll loop since there might be work to do to drop everything.
4248 mLooper->wake();
4249}
4250
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004251void InputDispatcher::setInTouchMode(bool inTouchMode) {
4252 std::scoped_lock lock(mLock);
4253 mInTouchMode = inTouchMode;
4254}
4255
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004256void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4257 if (opacity < 0 || opacity > 1) {
4258 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4259 return;
4260 }
4261
4262 std::scoped_lock lock(mLock);
4263 mMaximumObscuringOpacityForTouch = opacity;
4264}
4265
4266void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4267 std::scoped_lock lock(mLock);
4268 mBlockUntrustedTouchesMode = mode;
4269}
4270
chaviwfbe5d9c2018-12-26 12:23:37 -08004271bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4272 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004273 if (DEBUG_FOCUS) {
4274 ALOGD("Trivial transfer to same window.");
4275 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004276 return true;
4277 }
4278
Michael Wrightd02c5b62014-02-10 15:10:22 -08004279 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004280 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004281
chaviwfbe5d9c2018-12-26 12:23:37 -08004282 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4283 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004284 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004285 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004286 return false;
4287 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004288 if (DEBUG_FOCUS) {
4289 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4290 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4291 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004292 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004293 if (DEBUG_FOCUS) {
4294 ALOGD("Cannot transfer focus because windows are on different displays.");
4295 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004296 return false;
4297 }
4298
4299 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004300 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4301 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004302 for (size_t i = 0; i < state.windows.size(); i++) {
4303 const TouchedWindow& touchedWindow = state.windows[i];
4304 if (touchedWindow.windowHandle == fromWindowHandle) {
4305 int32_t oldTargetFlags = touchedWindow.targetFlags;
4306 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004307
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004308 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004309
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004310 int32_t newTargetFlags = oldTargetFlags &
4311 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4312 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004313 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004314
Jeff Brownf086ddb2014-02-11 14:28:48 -08004315 found = true;
4316 goto Found;
4317 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004318 }
4319 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004320 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004321
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004322 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004323 if (DEBUG_FOCUS) {
4324 ALOGD("Focus transfer failed because from window did not have focus.");
4325 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004326 return false;
4327 }
4328
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004329 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4330 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004331 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004332 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004333 CancelationOptions
4334 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4335 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004336 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004337 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004338 }
4339
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004340 if (DEBUG_FOCUS) {
4341 logDispatchStateLocked();
4342 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004343 } // release lock
4344
4345 // Wake up poll loop since it may need to make new input dispatching choices.
4346 mLooper->wake();
4347 return true;
4348}
4349
4350void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004351 if (DEBUG_FOCUS) {
4352 ALOGD("Resetting and dropping all events (%s).", reason);
4353 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004354
4355 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4356 synthesizeCancelationEventsForAllConnectionsLocked(options);
4357
4358 resetKeyRepeatLocked();
4359 releasePendingEventLocked();
4360 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004361 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004362
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004363 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004364 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004365 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004366 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004367}
4368
4369void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004370 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004371 dumpDispatchStateLocked(dump);
4372
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004373 std::istringstream stream(dump);
4374 std::string line;
4375
4376 while (std::getline(stream, line, '\n')) {
4377 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004378 }
4379}
4380
Vishnu Nairad321cd2020-08-20 16:40:21 -07004381std::string InputDispatcher::dumpFocusedWindowsLocked() {
4382 if (mFocusedWindowTokenByDisplay.empty()) {
4383 return INDENT "FocusedWindows: <none>\n";
4384 }
4385
4386 std::string dump;
4387 dump += INDENT "FocusedWindows:\n";
4388 for (auto& it : mFocusedWindowTokenByDisplay) {
4389 const int32_t displayId = it.first;
4390 const sp<InputWindowHandle> windowHandle = getFocusedWindowHandleLocked(displayId);
4391 if (windowHandle) {
4392 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
4393 windowHandle->getName().c_str());
4394 } else {
4395 dump += StringPrintf(INDENT2 "displayId=%" PRId32
4396 " has focused token without a window'\n",
4397 displayId);
4398 }
4399 }
4400 return dump;
4401}
4402
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004403void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004404 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4405 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4406 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004407 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004408
Tiger Huang721e26f2018-07-24 22:26:19 +08004409 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4410 dump += StringPrintf(INDENT "FocusedApplications:\n");
4411 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4412 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004413 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004414 const std::chrono::duration timeout =
4415 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004416 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004417 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004418 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004419 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004420 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004421 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004422 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004423
Vishnu Nairad321cd2020-08-20 16:40:21 -07004424 dump += dumpFocusedWindowsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004425
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004426 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004427 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004428 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4429 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004430 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004431 state.displayId, toString(state.down), toString(state.split),
4432 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004433 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004434 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004435 for (size_t i = 0; i < state.windows.size(); i++) {
4436 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004437 dump += StringPrintf(INDENT4
4438 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4439 i, touchedWindow.windowHandle->getName().c_str(),
4440 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004441 }
4442 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004443 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004444 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004445 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004446 dump += INDENT3 "Portal windows:\n";
4447 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004448 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004449 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4450 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004451 }
4452 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004453 }
4454 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004455 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004456 }
4457
Arthur Hungb92218b2018-08-14 12:00:21 +08004458 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004459 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004460 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004461 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004462 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004463 dump += INDENT2 "Windows:\n";
4464 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004465 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004466 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004467
Arthur Hungb92218b2018-08-14 12:00:21 +08004468 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004469 "portalToDisplayId=%d, paused=%s, focusable=%s, "
4470 "hasWallpaper=%s, visible=%s, "
Michael Wright44753b12020-07-08 13:48:11 +01004471 "flags=%s, type=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004472 "frame=[%d,%d][%d,%d], globalScale=%f, "
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004473 "applicationInfo=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004474 "touchableRegion=",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004475 i, windowInfo->name.c_str(), windowInfo->displayId,
4476 windowInfo->portalToDisplayId,
4477 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004478 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004479 toString(windowInfo->hasWallpaper),
4480 toString(windowInfo->visible),
Michael Wright8759d672020-07-21 00:46:45 +01004481 windowInfo->flags.string().c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004482 static_cast<int32_t>(windowInfo->type),
4483 windowInfo->frameLeft, windowInfo->frameTop,
4484 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004485 windowInfo->globalScaleFactor,
4486 windowInfo->applicationInfo.name.c_str());
Arthur Hungb92218b2018-08-14 12:00:21 +08004487 dumpRegion(dump, windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004488 dump += StringPrintf(", inputFeatures=%s",
4489 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004490 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
4491 "ms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004492 windowInfo->ownerPid, windowInfo->ownerUid,
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05004493 millis(windowInfo->dispatchingTimeout));
chaviw85b44202020-07-24 11:46:21 -07004494 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004495 }
4496 } else {
4497 dump += INDENT2 "Windows: <none>\n";
4498 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004499 }
4500 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004501 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004502 }
4503
Michael Wright3dd60e22019-03-27 22:06:44 +00004504 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004505 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004506 const std::vector<Monitor>& monitors = it.second;
4507 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4508 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004509 }
4510 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004511 const std::vector<Monitor>& monitors = it.second;
4512 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4513 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004514 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004515 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004516 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004517 }
4518
4519 nsecs_t currentTime = now();
4520
4521 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004522 if (!mRecentQueue.empty()) {
4523 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004524 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004525 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004526 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004527 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004528 }
4529 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004530 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004531 }
4532
4533 // Dump event currently being dispatched.
4534 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004535 dump += INDENT "PendingEvent:\n";
4536 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004537 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004538 dump += StringPrintf(", age=%" PRId64 "ms\n",
4539 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004540 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004541 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004542 }
4543
4544 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004545 if (!mInboundQueue.empty()) {
4546 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004547 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004548 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004549 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004550 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004551 }
4552 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004553 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004554 }
4555
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004556 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004557 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004558 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4559 const KeyReplacement& replacement = pair.first;
4560 int32_t newKeyCode = pair.second;
4561 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004562 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004563 }
4564 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004565 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004566 }
4567
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004568 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004569 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004570 for (const auto& pair : mConnectionsByFd) {
4571 const sp<Connection>& connection = pair.second;
4572 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004573 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004574 pair.first, connection->getInputChannelName().c_str(),
4575 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004576 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004577
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004578 if (!connection->outboundQueue.empty()) {
4579 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4580 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004581 dump += dumpQueue(connection->outboundQueue, currentTime);
4582
Michael Wrightd02c5b62014-02-10 15:10:22 -08004583 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004584 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004585 }
4586
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004587 if (!connection->waitQueue.empty()) {
4588 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4589 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004590 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004591 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004592 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004593 }
4594 }
4595 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004596 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004597 }
4598
4599 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004600 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4601 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004602 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004603 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004604 }
4605
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004606 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004607 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4608 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4609 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004610}
4611
Michael Wright3dd60e22019-03-27 22:06:44 +00004612void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4613 const size_t numMonitors = monitors.size();
4614 for (size_t i = 0; i < numMonitors; i++) {
4615 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004616 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004617 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4618 dump += "\n";
4619 }
4620}
4621
Garfield Tan15601662020-09-22 15:32:38 -07004622base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4623 const std::string& name) {
4624#if DEBUG_CHANNEL_CREATION
4625 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004626#endif
4627
Garfield Tan15601662020-09-22 15:32:38 -07004628 std::shared_ptr<InputChannel> serverChannel;
4629 std::unique_ptr<InputChannel> clientChannel;
4630 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4631
4632 if (result) {
4633 return base::Error(result) << "Failed to open input channel pair with name " << name;
4634 }
4635
Michael Wrightd02c5b62014-02-10 15:10:22 -08004636 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004637 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004638 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004639
Garfield Tan15601662020-09-22 15:32:38 -07004640 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004641 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004642 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004643
Michael Wrightd02c5b62014-02-10 15:10:22 -08004644 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4645 } // release lock
4646
4647 // Wake the looper because some connections have changed.
4648 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004649 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004650}
4651
Garfield Tan15601662020-09-22 15:32:38 -07004652base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
4653 int32_t displayId, bool isGestureMonitor, const std::string& name) {
4654 std::shared_ptr<InputChannel> serverChannel;
4655 std::unique_ptr<InputChannel> clientChannel;
4656 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4657 if (result) {
4658 return base::Error(result) << "Failed to open input channel pair with name " << name;
4659 }
4660
Michael Wright3dd60e22019-03-27 22:06:44 +00004661 { // acquire lock
4662 std::scoped_lock _l(mLock);
4663
4664 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004665 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4666 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004667 }
4668
Garfield Tan15601662020-09-22 15:32:38 -07004669 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004670
Garfield Tan15601662020-09-22 15:32:38 -07004671 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004672 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004673 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004674
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004675 auto& monitorsByDisplay =
4676 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Garfield Tan15601662020-09-22 15:32:38 -07004677 monitorsByDisplay[displayId].emplace_back(serverChannel);
Michael Wright3dd60e22019-03-27 22:06:44 +00004678
4679 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004680 }
Garfield Tan15601662020-09-22 15:32:38 -07004681
Michael Wright3dd60e22019-03-27 22:06:44 +00004682 // Wake the looper because some connections have changed.
4683 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004684 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004685}
4686
Garfield Tan15601662020-09-22 15:32:38 -07004687status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004688 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004689 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004690
Garfield Tan15601662020-09-22 15:32:38 -07004691 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004692 if (status) {
4693 return status;
4694 }
4695 } // release lock
4696
4697 // Wake the poll loop because removing the connection may have changed the current
4698 // synchronization state.
4699 mLooper->wake();
4700 return OK;
4701}
4702
Garfield Tan15601662020-09-22 15:32:38 -07004703status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
4704 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004705 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004706 if (connection == nullptr) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004707 ALOGW("Attempted to unregister already unregistered input channel");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004708 return BAD_VALUE;
4709 }
4710
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004711 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004712 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07004713
Michael Wrightd02c5b62014-02-10 15:10:22 -08004714 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004715 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004716 }
4717
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004718 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004719
4720 nsecs_t currentTime = now();
4721 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4722
4723 connection->status = Connection::STATUS_ZOMBIE;
4724 return OK;
4725}
4726
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004727void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
4728 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
4729 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00004730}
4731
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004732void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004733 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00004734 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004735 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004736 std::vector<Monitor>& monitors = it->second;
4737 const size_t numMonitors = monitors.size();
4738 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004739 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004740 monitors.erase(monitors.begin() + i);
4741 break;
4742 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004743 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004744 if (monitors.empty()) {
4745 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004746 } else {
4747 ++it;
4748 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004749 }
4750}
4751
Michael Wright3dd60e22019-03-27 22:06:44 +00004752status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4753 { // acquire lock
4754 std::scoped_lock _l(mLock);
4755 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4756
4757 if (!foundDisplayId) {
4758 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4759 return BAD_VALUE;
4760 }
4761 int32_t displayId = foundDisplayId.value();
4762
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004763 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4764 mTouchStatesByDisplay.find(displayId);
4765 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004766 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4767 return BAD_VALUE;
4768 }
4769
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004770 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00004771 std::optional<int32_t> foundDeviceId;
4772 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004773 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004774 foundDeviceId = state.deviceId;
4775 }
4776 }
4777 if (!foundDeviceId || !state.down) {
4778 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004779 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004780 return BAD_VALUE;
4781 }
4782 int32_t deviceId = foundDeviceId.value();
4783
4784 // Send cancel events to all the input channels we're stealing from.
4785 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004786 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004787 options.deviceId = deviceId;
4788 options.displayId = displayId;
4789 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004790 std::shared_ptr<InputChannel> channel =
4791 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004792 if (channel != nullptr) {
4793 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4794 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004795 }
4796 // Then clear the current touch state so we stop dispatching to them as well.
4797 state.filterNonMonitors();
4798 }
4799 return OK;
4800}
4801
Michael Wright3dd60e22019-03-27 22:06:44 +00004802std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4803 const sp<IBinder>& token) {
4804 for (const auto& it : mGestureMonitorsByDisplay) {
4805 const std::vector<Monitor>& monitors = it.second;
4806 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004807 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004808 return it.first;
4809 }
4810 }
4811 }
4812 return std::nullopt;
4813}
4814
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004815sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004816 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004817 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004818 }
4819
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004820 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004821 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004822 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004823 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004824 }
4825 }
Robert Carr4e670e52018-08-15 13:26:12 -07004826
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004827 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004828}
4829
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004830void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004831 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004832 removeByValue(mConnectionsByFd, connection);
4833}
4834
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004835void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4836 const sp<Connection>& connection, uint32_t seq,
4837 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004838 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4839 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004840 commandEntry->connection = connection;
4841 commandEntry->eventTime = currentTime;
4842 commandEntry->seq = seq;
4843 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004844 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004845}
4846
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004847void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4848 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004849 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004850 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004851
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004852 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4853 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004854 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004855 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004856}
4857
Vishnu Nairad321cd2020-08-20 16:40:21 -07004858void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
4859 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004860 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4861 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004862 commandEntry->oldToken = oldToken;
4863 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004864 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004865}
4866
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004867void InputDispatcher::onAnrLocked(const Connection& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004868 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
4869 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004870 if (connection.waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004871 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004872 connection.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004873 return;
4874 }
4875 /**
4876 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
4877 * may not be the one that caused the timeout to occur. One possibility is that window timeout
4878 * has changed. This could cause newer entries to time out before the already dispatched
4879 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
4880 * processes the events linearly. So providing information about the oldest entry seems to be
4881 * most useful.
4882 */
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004883 DispatchEntry* oldestEntry = *connection.waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004884 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
4885 std::string reason =
4886 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004887 connection.inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004888 ns2ms(currentWait),
4889 oldestEntry->eventEntry->getDescription().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004890
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004891 updateLastAnrStateLocked(getWindowHandleLocked(connection.inputChannel->getConnectionToken()),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004892 reason);
4893
4894 std::unique_ptr<CommandEntry> commandEntry =
4895 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyAnrLockedInterruptible);
4896 commandEntry->inputApplicationHandle = nullptr;
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05004897 commandEntry->inputChannel = connection.inputChannel;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004898 commandEntry->reason = std::move(reason);
4899 postCommandLocked(std::move(commandEntry));
4900}
4901
Chris Yea209fde2020-07-22 13:54:51 -07004902void InputDispatcher::onAnrLocked(const std::shared_ptr<InputApplicationHandle>& application) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004903 std::string reason = android::base::StringPrintf("%s does not have a focused window",
4904 application->getName().c_str());
4905
4906 updateLastAnrStateLocked(application, reason);
4907
4908 std::unique_ptr<CommandEntry> commandEntry =
4909 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyAnrLockedInterruptible);
4910 commandEntry->inputApplicationHandle = application;
4911 commandEntry->inputChannel = nullptr;
4912 commandEntry->reason = std::move(reason);
4913 postCommandLocked(std::move(commandEntry));
4914}
4915
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00004916void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
4917 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4918 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
4919 commandEntry->obscuringPackage = obscuringPackage;
4920 postCommandLocked(std::move(commandEntry));
4921}
4922
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004923void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
4924 const std::string& reason) {
4925 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
4926 updateLastAnrStateLocked(windowLabel, reason);
4927}
4928
Chris Yea209fde2020-07-22 13:54:51 -07004929void InputDispatcher::updateLastAnrStateLocked(
4930 const std::shared_ptr<InputApplicationHandle>& application, const std::string& reason) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004931 const std::string windowLabel = getApplicationWindowLabel(application, nullptr);
4932 updateLastAnrStateLocked(windowLabel, reason);
4933}
4934
4935void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
4936 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004937 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004938 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004939 struct tm tm;
4940 localtime_r(&t, &tm);
4941 char timestr[64];
4942 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07004943 mLastAnrState.clear();
4944 mLastAnrState += INDENT "ANR:\n";
4945 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004946 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
4947 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07004948 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004949}
4950
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004951void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004952 mLock.unlock();
4953
4954 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4955
4956 mLock.lock();
4957}
4958
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004959void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004960 sp<Connection> connection = commandEntry->connection;
4961
4962 if (connection->status != Connection::STATUS_ZOMBIE) {
4963 mLock.unlock();
4964
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004965 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004966
4967 mLock.lock();
4968 }
4969}
4970
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004971void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004972 sp<IBinder> oldToken = commandEntry->oldToken;
4973 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004974 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004975 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004976 mLock.lock();
4977}
4978
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07004979void InputDispatcher::doNotifyAnrLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004980 sp<IBinder> token =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004981 commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004982 mLock.unlock();
4983
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05004984 const std::chrono::nanoseconds timeoutExtension =
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07004985 mPolicy->notifyAnr(commandEntry->inputApplicationHandle, token, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004986
4987 mLock.lock();
4988
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05004989 if (timeoutExtension > 0s) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004990 extendAnrTimeoutsLocked(commandEntry->inputApplicationHandle, token, timeoutExtension);
4991 } else {
4992 // stop waking up for events in this connection, it is already not responding
4993 sp<Connection> connection = getConnectionLocked(token);
4994 if (connection == nullptr) {
4995 return;
4996 }
4997 cancelEventsForAnrLocked(connection);
4998 }
4999}
5000
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005001void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5002 mLock.unlock();
5003
5004 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5005
5006 mLock.lock();
5007}
5008
Chris Yea209fde2020-07-22 13:54:51 -07005009void InputDispatcher::extendAnrTimeoutsLocked(
5010 const std::shared_ptr<InputApplicationHandle>& application,
5011 const sp<IBinder>& connectionToken, std::chrono::nanoseconds timeoutExtension) {
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005012 if (connectionToken == nullptr && application != nullptr) {
5013 // The ANR happened because there's no focused window
5014 mNoFocusedWindowTimeoutTime = now() + timeoutExtension.count();
5015 mAwaitedFocusedApplication = application;
5016 }
5017
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005018 sp<Connection> connection = getConnectionLocked(connectionToken);
5019 if (connection == nullptr) {
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005020 // It's possible that the connection already disappeared. No action necessary.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005021 return;
5022 }
5023
5024 ALOGI("Raised ANR, but the policy wants to keep waiting on %s for %" PRId64 "ms longer",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05005025 connection->inputChannel->getName().c_str(), millis(timeoutExtension));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005026
5027 connection->responsive = true;
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05005028 const nsecs_t newTimeout = now() + timeoutExtension.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005029 for (DispatchEntry* entry : connection->waitQueue) {
5030 if (newTimeout >= entry->timeoutTime) {
5031 // Already removed old entries when connection was marked unresponsive
5032 entry->timeoutTime = newTimeout;
5033 mAnrTracker.insert(entry->timeoutTime, connectionToken);
5034 }
5035 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005036}
5037
5038void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5039 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005040 KeyEntry& entry = *(commandEntry->keyEntry);
5041 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005042
5043 mLock.unlock();
5044
Michael Wright2b3c3302018-03-02 17:19:13 +00005045 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005046 sp<IBinder> token = commandEntry->inputChannel != nullptr
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005047 ? commandEntry->inputChannel->getConnectionToken()
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005048 : nullptr;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005049 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005050 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5051 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005052 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005053 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005054
5055 mLock.lock();
5056
5057 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005058 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005059 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005060 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005061 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005062 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5063 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005064 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005065}
5066
chaviwfd6d3512019-03-25 13:23:49 -07005067void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5068 mLock.unlock();
5069 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5070 mLock.lock();
5071}
5072
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005073/**
5074 * Connection is responsive if it has no events in the waitQueue that are older than the
5075 * current time.
5076 */
5077static bool isConnectionResponsive(const Connection& connection) {
5078 const nsecs_t currentTime = now();
5079 for (const DispatchEntry* entry : connection.waitQueue) {
5080 if (entry->timeoutTime < currentTime) {
5081 return false;
5082 }
5083 }
5084 return true;
5085}
5086
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005087void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005088 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005089 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005090 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005091 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005092
5093 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005094 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005095 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005096 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005097 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005098 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005099 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005100 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005101 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5102 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005103 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005104 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005105
5106 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005107 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005108 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005109 restartEvent =
5110 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005111 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005112 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005113 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5114 handled);
5115 } else {
5116 restartEvent = false;
5117 }
5118
5119 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005120 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005121 // contents of the wait queue to have been drained, so we need to double-check
5122 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005123 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5124 if (dispatchEntryIt != connection->waitQueue.end()) {
5125 dispatchEntry = *dispatchEntryIt;
5126 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005127 mAnrTracker.erase(dispatchEntry->timeoutTime,
5128 connection->inputChannel->getConnectionToken());
5129 if (!connection->responsive) {
5130 connection->responsive = isConnectionResponsive(*connection);
5131 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005132 traceWaitQueueLength(connection);
5133 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005134 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005135 traceOutboundQueueLength(connection);
5136 } else {
5137 releaseDispatchEntry(dispatchEntry);
5138 }
5139 }
5140
5141 // Start the next dispatch cycle for this connection.
5142 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005143}
5144
5145bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005146 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005147 KeyEntry& keyEntry, bool handled) {
5148 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005149 if (!handled) {
5150 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005151 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005152 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005153 return false;
5154 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005155
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005156 // Get the fallback key state.
5157 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005158 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005159 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005160 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005161 connection->inputState.removeFallbackKey(originalKeyCode);
5162 }
5163
5164 if (handled || !dispatchEntry->hasForegroundTarget()) {
5165 // If the application handles the original key for which we previously
5166 // generated a fallback or if the window is not a foreground window,
5167 // then cancel the associated fallback key, if any.
5168 if (fallbackKeyCode != -1) {
5169 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005170#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005171 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005172 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005173 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005174#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005175 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005176 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005177
5178 mLock.unlock();
5179
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005180 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005181 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005182
5183 mLock.lock();
5184
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005185 // Cancel the fallback key.
5186 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005187 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005188 "application handled the original non-fallback key "
5189 "or is no longer a foreground target, "
5190 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005191 options.keyCode = fallbackKeyCode;
5192 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005193 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005194 connection->inputState.removeFallbackKey(originalKeyCode);
5195 }
5196 } else {
5197 // If the application did not handle a non-fallback key, first check
5198 // that we are in a good state to perform unhandled key event processing
5199 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005200 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005201 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005202#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005203 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005204 "since this is not an initial down. "
5205 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005206 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005207#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005208 return false;
5209 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005210
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005211 // Dispatch the unhandled key to the policy.
5212#if DEBUG_OUTBOUND_EVENT_DETAILS
5213 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005214 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005215 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005216#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005217 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005218
5219 mLock.unlock();
5220
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005221 bool fallback =
5222 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005223 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005224
5225 mLock.lock();
5226
5227 if (connection->status != Connection::STATUS_NORMAL) {
5228 connection->inputState.removeFallbackKey(originalKeyCode);
5229 return false;
5230 }
5231
5232 // Latch the fallback keycode for this key on an initial down.
5233 // The fallback keycode cannot change at any other point in the lifecycle.
5234 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005235 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005236 fallbackKeyCode = event.getKeyCode();
5237 } else {
5238 fallbackKeyCode = AKEYCODE_UNKNOWN;
5239 }
5240 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5241 }
5242
5243 ALOG_ASSERT(fallbackKeyCode != -1);
5244
5245 // Cancel the fallback key if the policy decides not to send it anymore.
5246 // We will continue to dispatch the key to the policy but we will no
5247 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005248 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5249 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005250#if DEBUG_OUTBOUND_EVENT_DETAILS
5251 if (fallback) {
5252 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005253 "as a fallback for %d, but on the DOWN it had requested "
5254 "to send %d instead. Fallback canceled.",
5255 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005256 } else {
5257 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005258 "but on the DOWN it had requested to send %d. "
5259 "Fallback canceled.",
5260 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005261 }
5262#endif
5263
5264 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5265 "canceling fallback, policy no longer desires it");
5266 options.keyCode = fallbackKeyCode;
5267 synthesizeCancelationEventsForConnectionLocked(connection, options);
5268
5269 fallback = false;
5270 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005271 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005272 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005273 }
5274 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005275
5276#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005277 {
5278 std::string msg;
5279 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5280 connection->inputState.getFallbackKeys();
5281 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005282 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005283 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005284 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005285 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005286 }
5287#endif
5288
5289 if (fallback) {
5290 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005291 keyEntry.eventTime = event.getEventTime();
5292 keyEntry.deviceId = event.getDeviceId();
5293 keyEntry.source = event.getSource();
5294 keyEntry.displayId = event.getDisplayId();
5295 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5296 keyEntry.keyCode = fallbackKeyCode;
5297 keyEntry.scanCode = event.getScanCode();
5298 keyEntry.metaState = event.getMetaState();
5299 keyEntry.repeatCount = event.getRepeatCount();
5300 keyEntry.downTime = event.getDownTime();
5301 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005302
5303#if DEBUG_OUTBOUND_EVENT_DETAILS
5304 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005305 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005306 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005307#endif
5308 return true; // restart the event
5309 } else {
5310#if DEBUG_OUTBOUND_EVENT_DETAILS
5311 ALOGD("Unhandled key event: No fallback key.");
5312#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005313
5314 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005315 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005316 }
5317 }
5318 return false;
5319}
5320
5321bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005322 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005323 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005324 return false;
5325}
5326
5327void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5328 mLock.unlock();
5329
5330 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5331
5332 mLock.lock();
5333}
5334
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005335KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
5336 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08005337 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08005338 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
5339 entry.repeatCount, entry.downTime, entry.eventTime);
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005340 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005341}
5342
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005343void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5344 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005345 // TODO Write some statistics about how long we spend waiting.
5346}
5347
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005348/**
5349 * Report the touch event latency to the statsd server.
5350 * Input events are reported for statistics if:
5351 * - This is a touchscreen event
5352 * - InputFilter is not enabled
5353 * - Event is not injected or synthesized
5354 *
5355 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5356 * from getting aggregated with the "old" data.
5357 */
5358void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5359 REQUIRES(mLock) {
5360 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5361 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5362 if (!reportForStatistics) {
5363 return;
5364 }
5365
5366 if (mTouchStatistics.shouldReport()) {
5367 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5368 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5369 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5370 mTouchStatistics.reset();
5371 }
5372 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5373 mTouchStatistics.addValue(latencyMicros);
5374}
5375
Michael Wrightd02c5b62014-02-10 15:10:22 -08005376void InputDispatcher::traceInboundQueueLengthLocked() {
5377 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005378 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005379 }
5380}
5381
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005382void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005383 if (ATRACE_ENABLED()) {
5384 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005385 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005386 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005387 }
5388}
5389
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005390void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005391 if (ATRACE_ENABLED()) {
5392 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005393 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005394 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005395 }
5396}
5397
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005398void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005399 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005400
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005401 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005402 dumpDispatchStateLocked(dump);
5403
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005404 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005405 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005406 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005407 }
5408}
5409
5410void InputDispatcher::monitor() {
5411 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005412 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005413 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005414 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005415}
5416
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005417/**
5418 * Wake up the dispatcher and wait until it processes all events and commands.
5419 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5420 * this method can be safely called from any thread, as long as you've ensured that
5421 * the work you are interested in completing has already been queued.
5422 */
5423bool InputDispatcher::waitForIdle() {
5424 /**
5425 * Timeout should represent the longest possible time that a device might spend processing
5426 * events and commands.
5427 */
5428 constexpr std::chrono::duration TIMEOUT = 100ms;
5429 std::unique_lock lock(mLock);
5430 mLooper->wake();
5431 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5432 return result == std::cv_status::no_timeout;
5433}
5434
Vishnu Naire798b472020-07-23 13:52:21 -07005435/**
5436 * Sets focus to the window identified by the token. This must be called
5437 * after updating any input window handles.
5438 *
5439 * Params:
5440 * request.token - input channel token used to identify the window that should gain focus.
5441 * request.focusedToken - the token that the caller expects currently to be focused. If the
5442 * specified token does not match the currently focused window, this request will be dropped.
5443 * If the specified focused token matches the currently focused window, the call will succeed.
5444 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5445 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5446 * when requesting the focus change. This determines which request gets
5447 * precedence if there is a focus change request from another source such as pointer down.
5448 */
Vishnu Nair958da932020-08-21 17:12:37 -07005449void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5450 { // acquire lock
5451 std::scoped_lock _l(mLock);
5452
5453 const int32_t displayId = request.displayId;
5454 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5455 if (request.focusedToken && oldFocusedToken != request.focusedToken) {
5456 ALOGD_IF(DEBUG_FOCUS,
5457 "setFocusedWindow on display %" PRId32
5458 " ignored, reason: focusedToken is not focused",
5459 displayId);
5460 return;
5461 }
5462
5463 mPendingFocusRequests.erase(displayId);
5464 FocusResult result = handleFocusRequestLocked(request);
5465 if (result == FocusResult::NOT_VISIBLE) {
5466 // The requested window is not currently visible. Wait for the window to become visible
5467 // and then provide it focus. This is to handle situations where a user action triggers
5468 // a new window to appear. We want to be able to queue any key events after the user
5469 // action and deliver it to the newly focused window. In order for this to happen, we
5470 // take focus from the currently focused window so key events can be queued.
5471 ALOGD_IF(DEBUG_FOCUS,
5472 "setFocusedWindow on display %" PRId32
5473 " pending, reason: window is not visible",
5474 displayId);
5475 mPendingFocusRequests[displayId] = request;
5476 onFocusChangedLocked(oldFocusedToken, nullptr, displayId,
5477 "setFocusedWindow_AwaitingWindowVisibility");
5478 } else if (result != FocusResult::OK) {
5479 ALOGW("setFocusedWindow on display %" PRId32 " ignored, reason:%s", displayId,
5480 typeToString(result));
5481 }
5482 } // release lock
5483 // Wake up poll loop since it may need to make new input dispatching choices.
5484 mLooper->wake();
5485}
5486
5487InputDispatcher::FocusResult InputDispatcher::handleFocusRequestLocked(
5488 const FocusRequest& request) {
5489 const int32_t displayId = request.displayId;
5490 const sp<IBinder> newFocusedToken = request.token;
5491 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5492
5493 if (oldFocusedToken == request.token) {
5494 ALOGD_IF(DEBUG_FOCUS,
5495 "setFocusedWindow on display %" PRId32 " ignored, reason: already focused",
5496 displayId);
5497 return FocusResult::OK;
5498 }
5499
5500 FocusResult result = checkTokenFocusableLocked(newFocusedToken, displayId);
5501 if (result != FocusResult::OK) {
5502 return result;
5503 }
5504
5505 std::string_view reason =
5506 (request.focusedToken) ? "setFocusedWindow_FocusCheck" : "setFocusedWindow";
5507 onFocusChangedLocked(oldFocusedToken, newFocusedToken, displayId, reason);
5508 return FocusResult::OK;
5509}
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005510
Vishnu Nairad321cd2020-08-20 16:40:21 -07005511void InputDispatcher::onFocusChangedLocked(const sp<IBinder>& oldFocusedToken,
5512 const sp<IBinder>& newFocusedToken, int32_t displayId,
5513 std::string_view reason) {
5514 if (oldFocusedToken) {
5515 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(oldFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005516 if (focusedInputChannel) {
5517 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5518 "focus left window");
5519 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005520 enqueueFocusEventLocked(oldFocusedToken, false /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005521 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005522 mFocusedWindowTokenByDisplay.erase(displayId);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005523 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005524 if (newFocusedToken) {
5525 mFocusedWindowTokenByDisplay[displayId] = newFocusedToken;
5526 enqueueFocusEventLocked(newFocusedToken, true /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005527 }
5528
5529 if (mFocusedDisplayId == displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005530 notifyFocusChangedLocked(oldFocusedToken, newFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005531 }
5532}
Vishnu Nair958da932020-08-21 17:12:37 -07005533
5534/**
5535 * Checks if the window token can be focused on a display. The token can be focused if there is
5536 * at least one window handle that is visible with the same token and all window handles with the
5537 * same token are focusable.
5538 *
5539 * In the case of mirroring, two windows may share the same window token and their visibility
5540 * might be different. Example, the mirrored window can cover the window its mirroring. However,
5541 * we expect the focusability of the windows to match since its hard to reason why one window can
5542 * receive focus events and the other cannot when both are backed by the same input channel.
5543 */
5544InputDispatcher::FocusResult InputDispatcher::checkTokenFocusableLocked(const sp<IBinder>& token,
5545 int32_t displayId) const {
5546 bool allWindowsAreFocusable = true;
5547 bool visibleWindowFound = false;
5548 bool windowFound = false;
5549 for (const sp<InputWindowHandle>& window : getWindowHandlesLocked(displayId)) {
5550 if (window->getToken() != token) {
5551 continue;
5552 }
5553 windowFound = true;
5554 if (window->getInfo()->visible) {
5555 // Check if at least a single window is visible.
5556 visibleWindowFound = true;
5557 }
5558 if (!window->getInfo()->focusable) {
5559 // Check if all windows with the window token are focusable.
5560 allWindowsAreFocusable = false;
5561 break;
5562 }
5563 }
5564
5565 if (!windowFound) {
5566 return FocusResult::NO_WINDOW;
5567 }
5568 if (!allWindowsAreFocusable) {
5569 return FocusResult::NOT_FOCUSABLE;
5570 }
5571 if (!visibleWindowFound) {
5572 return FocusResult::NOT_VISIBLE;
5573 }
5574
5575 return FocusResult::OK;
5576}
Garfield Tane84e6f92019-08-29 17:28:41 -07005577} // namespace android::inputdispatcher