blob: ba01adea533303992a5d206aa664dc4eac109acd [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 Vishniakou2508b872020-12-03 16:33:53 -100056#include <binder/IServiceManager.h>
57#include <com/android/internal/compat/IPlatformCompatNative.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080058#include <input/InputDevice.h>
Michael Wright44753b12020-07-08 13:48:11 +010059#include <input/InputWindow.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070060#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000061#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070062#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010063#include <statslog.h>
64#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070065#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080066
Michael Wright44753b12020-07-08 13:48:11 +010067#include <cerrno>
68#include <cinttypes>
69#include <climits>
70#include <cstddef>
71#include <ctime>
72#include <queue>
73#include <sstream>
74
75#include "Connection.h"
76
Michael Wrightd02c5b62014-02-10 15:10:22 -080077#define INDENT " "
78#define INDENT2 " "
79#define INDENT3 " "
80#define INDENT4 " "
81
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080082using android::base::StringPrintf;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080083using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100084using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080085using android::os::InputEventInjectionResult;
86using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100087using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080088
Garfield Tane84e6f92019-08-29 17:28:41 -070089namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080090
91// Default input dispatching timeout if there is no focused application or paused window
92// from which to determine an appropriate dispatching timeout.
Siarhei Vishniakou70622952020-07-30 11:17:23 -050093constexpr std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT =
94 std::chrono::milliseconds(android::os::IInputConstants::DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
Michael Wrightd02c5b62014-02-10 15:10:22 -080095
96// Amount of time to allow for all pending events to be processed when an app switch
97// key is on the way. This is used to preempt input dispatch and drop input events
98// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000099constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800100
101// Amount of time to allow for an event to be dispatched (measured since its eventTime)
102// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000103constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104
Michael Wrightd02c5b62014-02-10 15:10:22 -0800105// 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 +0000106constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
107
108// Log a warning when an interception call takes longer than this to process.
109constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800110
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700111// Additional key latency in case a connection is still processing some motion events.
112// This will help with the case when a user touched a button that opens a new window,
113// and gives us the chance to dispatch the key to this new window.
114constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
115
Michael Wrightd02c5b62014-02-10 15:10:22 -0800116// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000117constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
118
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000119// Event log tags. See EventLogTags.logtags for reference
120constexpr int LOGTAG_INPUT_INTERACTION = 62000;
121constexpr int LOGTAG_INPUT_FOCUS = 62001;
122
Michael Wrightd02c5b62014-02-10 15:10:22 -0800123static inline nsecs_t now() {
124 return systemTime(SYSTEM_TIME_MONOTONIC);
125}
126
127static inline const char* toString(bool value) {
128 return value ? "true" : "false";
129}
130
131static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700132 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
133 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800134}
135
136static bool isValidKeyAction(int32_t action) {
137 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700138 case AKEY_EVENT_ACTION_DOWN:
139 case AKEY_EVENT_ACTION_UP:
140 return true;
141 default:
142 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800143 }
144}
145
146static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700147 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800148 ALOGE("Key event has invalid action code 0x%x", action);
149 return false;
150 }
151 return true;
152}
153
Michael Wright7b159c92015-05-14 14:48:03 +0100154static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800155 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700156 case AMOTION_EVENT_ACTION_DOWN:
157 case AMOTION_EVENT_ACTION_UP:
158 case AMOTION_EVENT_ACTION_CANCEL:
159 case AMOTION_EVENT_ACTION_MOVE:
160 case AMOTION_EVENT_ACTION_OUTSIDE:
161 case AMOTION_EVENT_ACTION_HOVER_ENTER:
162 case AMOTION_EVENT_ACTION_HOVER_MOVE:
163 case AMOTION_EVENT_ACTION_HOVER_EXIT:
164 case AMOTION_EVENT_ACTION_SCROLL:
165 return true;
166 case AMOTION_EVENT_ACTION_POINTER_DOWN:
167 case AMOTION_EVENT_ACTION_POINTER_UP: {
168 int32_t index = getMotionEventActionPointerIndex(action);
169 return index >= 0 && index < pointerCount;
170 }
171 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
172 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
173 return actionButton != 0;
174 default:
175 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800176 }
177}
178
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500179static int64_t millis(std::chrono::nanoseconds t) {
180 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
181}
182
Michael Wright7b159c92015-05-14 14:48:03 +0100183static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700184 const PointerProperties* pointerProperties) {
185 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186 ALOGE("Motion event has invalid action code 0x%x", action);
187 return false;
188 }
189 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000190 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700191 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800192 return false;
193 }
194 BitSet32 pointerIdBits;
195 for (size_t i = 0; i < pointerCount; i++) {
196 int32_t id = pointerProperties[i].id;
197 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700198 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
199 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800200 return false;
201 }
202 if (pointerIdBits.hasBit(id)) {
203 ALOGE("Motion event has duplicate pointer id %d", id);
204 return false;
205 }
206 pointerIdBits.markBit(id);
207 }
208 return true;
209}
210
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000211static std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800212 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000213 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214 }
215
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000216 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217 bool first = true;
218 Region::const_iterator cur = region.begin();
219 Region::const_iterator const tail = region.end();
220 while (cur != tail) {
221 if (first) {
222 first = false;
223 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800224 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800225 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800226 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800227 cur++;
228 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000229 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800230}
231
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500232static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
233 constexpr size_t maxEntries = 50; // max events to print
234 constexpr size_t skipBegin = maxEntries / 2;
235 const size_t skipEnd = queue.size() - maxEntries / 2;
236 // skip from maxEntries / 2 ... size() - maxEntries/2
237 // only print from 0 .. skipBegin and then from skipEnd .. size()
238
239 std::string dump;
240 for (size_t i = 0; i < queue.size(); i++) {
241 const DispatchEntry& entry = *queue[i];
242 if (i >= skipBegin && i < skipEnd) {
243 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
244 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
245 continue;
246 }
247 dump.append(INDENT4);
248 dump += entry.eventEntry->getDescription();
249 dump += StringPrintf(", seq=%" PRIu32
250 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
251 entry.seq, entry.targetFlags, entry.resolvedAction,
252 ns2ms(currentTime - entry.eventEntry->eventTime));
253 if (entry.deliveryTime != 0) {
254 // This entry was delivered, so add information on how long we've been waiting
255 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
256 }
257 dump.append("\n");
258 }
259 return dump;
260}
261
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700262/**
263 * Find the entry in std::unordered_map by key, and return it.
264 * If the entry is not found, return a default constructed entry.
265 *
266 * Useful when the entries are vectors, since an empty vector will be returned
267 * if the entry is not found.
268 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
269 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700270template <typename K, typename V>
271static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700272 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700273 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800274}
275
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700276/**
277 * Find the entry in std::unordered_map by value, and remove it.
278 * If more than one entry has the same value, then all matching
279 * key-value pairs will be removed.
280 *
281 * Return true if at least one value has been removed.
282 */
283template <typename K, typename V>
284static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
285 bool removed = false;
286 for (auto it = map.begin(); it != map.end();) {
287 if (it->second == value) {
288 it = map.erase(it);
289 removed = true;
290 } else {
291 it++;
292 }
293 }
294 return removed;
295}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800296
Vishnu Nair958da932020-08-21 17:12:37 -0700297/**
298 * Find the entry in std::unordered_map by key and return the value as an optional.
299 */
300template <typename K, typename V>
301static std::optional<V> getOptionalValueByKey(const std::unordered_map<K, V>& map, K key) {
302 auto it = map.find(key);
303 return it != map.end() ? std::optional<V>{it->second} : std::nullopt;
304}
305
chaviwaf87b3e2019-10-01 16:59:28 -0700306static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
307 if (first == second) {
308 return true;
309 }
310
311 if (first == nullptr || second == nullptr) {
312 return false;
313 }
314
315 return first->getToken() == second->getToken();
316}
317
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800318static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
319 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
320}
321
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000322static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700323 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000324 int32_t inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700325 if (inputTarget.useDefaultPointerTransform()) {
326 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700327 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
chaviw1ff3d1e2020-07-01 15:53:47 -0700328 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000329 }
330
331 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
332 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
333
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700334 std::vector<PointerCoords> pointerCoords;
335 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000336
337 // Use the first pointer information to normalize all other pointers. This could be any pointer
338 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700339 // uses the transform for the normalized pointer.
340 const ui::Transform& firstPointerTransform =
341 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
342 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000343
344 // Iterate through all pointers in the event to normalize against the first.
345 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
346 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
347 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700348 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000349
350 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700351 // First, apply the current pointer's transform to update the coordinates into
352 // window space.
353 pointerCoords[pointerIndex].transform(currTransform);
354 // Next, apply the inverse transform of the normalized coordinates so the
355 // current coordinates are transformed into the normalized coordinate space.
356 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000357 }
358
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700359 std::unique_ptr<MotionEntry> combinedMotionEntry =
360 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
361 motionEntry.deviceId, motionEntry.source,
362 motionEntry.displayId, motionEntry.policyFlags,
363 motionEntry.action, motionEntry.actionButton,
364 motionEntry.flags, motionEntry.metaState,
365 motionEntry.buttonState, motionEntry.classification,
366 motionEntry.edgeFlags, motionEntry.xPrecision,
367 motionEntry.yPrecision, motionEntry.xCursorPosition,
368 motionEntry.yCursorPosition, motionEntry.downTime,
369 motionEntry.pointerCount, motionEntry.pointerProperties,
370 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000371
372 if (motionEntry.injectionState) {
373 combinedMotionEntry->injectionState = motionEntry.injectionState;
374 combinedMotionEntry->injectionState->refCount += 1;
375 }
376
377 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700378 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
379 firstPointerTransform, inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000380 return dispatchEntry;
381}
382
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700383static void addGestureMonitors(const std::vector<Monitor>& monitors,
384 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
385 float yOffset = 0) {
386 if (monitors.empty()) {
387 return;
388 }
389 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
390 for (const Monitor& monitor : monitors) {
391 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
392 }
393}
394
Garfield Tan15601662020-09-22 15:32:38 -0700395static status_t openInputChannelPair(const std::string& name,
396 std::shared_ptr<InputChannel>& serverChannel,
397 std::unique_ptr<InputChannel>& clientChannel) {
398 std::unique_ptr<InputChannel> uniqueServerChannel;
399 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
400
401 serverChannel = std::move(uniqueServerChannel);
402 return result;
403}
404
Vishnu Nair958da932020-08-21 17:12:37 -0700405const char* InputDispatcher::typeToString(InputDispatcher::FocusResult result) {
406 switch (result) {
407 case InputDispatcher::FocusResult::OK:
408 return "Ok";
409 case InputDispatcher::FocusResult::NO_WINDOW:
410 return "Window not found";
411 case InputDispatcher::FocusResult::NOT_FOCUSABLE:
412 return "Window not focusable";
413 case InputDispatcher::FocusResult::NOT_VISIBLE:
414 return "Window not visible";
415 }
416}
417
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500418template <typename T>
419static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
420 if (lhs == nullptr && rhs == nullptr) {
421 return true;
422 }
423 if (lhs == nullptr || rhs == nullptr) {
424 return false;
425 }
426 return *lhs == *rhs;
427}
428
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000429static sp<IPlatformCompatNative> getCompatService() {
430 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
431 if (service == nullptr) {
432 ALOGE("Failed to link to compat service");
433 return nullptr;
434 }
435 return interface_cast<IPlatformCompatNative>(service);
436}
437
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000438static KeyEvent createKeyEvent(const KeyEntry& entry) {
439 KeyEvent event;
440 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
441 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
442 entry.repeatCount, entry.downTime, entry.eventTime);
443 return event;
444}
445
Michael Wrightd02c5b62014-02-10 15:10:22 -0800446// --- InputDispatcher ---
447
Garfield Tan00f511d2019-06-12 16:55:40 -0700448InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
449 : mPolicy(policy),
450 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700451 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800452 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700453 mAppSwitchSawKeyDown(false),
454 mAppSwitchDueTime(LONG_LONG_MAX),
455 mNextUnblockedEvent(nullptr),
456 mDispatchEnabled(false),
457 mDispatchFrozen(false),
458 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800459 // mInTouchMode will be initialized by the WindowManager to the default device config.
460 // To avoid leaking stack in case that call never comes, and for tests,
461 // initialize it here anyways.
462 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100463 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000464 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800465 mFocusedWindowRequestedPointerCapture(false),
466 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000467 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800468 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800469 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800470
Yi Kong9b14ac62018-07-17 13:48:38 -0700471 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800472
473 policy->getDispatcherConfiguration(&mConfig);
474}
475
476InputDispatcher::~InputDispatcher() {
477 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800478 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800479
480 resetKeyRepeatLocked();
481 releasePendingEventLocked();
482 drainInboundQueueLocked();
483 }
484
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700485 while (!mConnectionsByFd.empty()) {
486 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700487 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800488 }
489}
490
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700491status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700492 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700493 return ALREADY_EXISTS;
494 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700495 mThread = std::make_unique<InputThread>(
496 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
497 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700498}
499
500status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700501 if (mThread && mThread->isCallingThread()) {
502 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700503 return INVALID_OPERATION;
504 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700505 mThread.reset();
506 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700507}
508
Michael Wrightd02c5b62014-02-10 15:10:22 -0800509void InputDispatcher::dispatchOnce() {
510 nsecs_t nextWakeupTime = LONG_LONG_MAX;
511 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800512 std::scoped_lock _l(mLock);
513 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800514
515 // Run a dispatch loop if there are no pending commands.
516 // The dispatch loop might enqueue commands to run afterwards.
517 if (!haveCommandsLocked()) {
518 dispatchOnceInnerLocked(&nextWakeupTime);
519 }
520
521 // Run all pending commands if there are any.
522 // If any commands were run then force the next poll to wake up immediately.
523 if (runCommandsLockedInterruptible()) {
524 nextWakeupTime = LONG_LONG_MIN;
525 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800526
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700527 // If we are still waiting for ack on some events,
528 // we might have to wake up earlier to check if an app is anr'ing.
529 const nsecs_t nextAnrCheck = processAnrsLocked();
530 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
531
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800532 // We are about to enter an infinitely long sleep, because we have no commands or
533 // pending or queued events
534 if (nextWakeupTime == LONG_LONG_MAX) {
535 mDispatcherEnteredIdle.notify_all();
536 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800537 } // release lock
538
539 // Wait for callback or timeout or wake. (make sure we round up, not down)
540 nsecs_t currentTime = now();
541 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
542 mLooper->pollOnce(timeoutMillis);
543}
544
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700545/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500546 * Raise ANR if there is no focused window.
547 * Before the ANR is raised, do a final state check:
548 * 1. The currently focused application must be the same one we are waiting for.
549 * 2. Ensure we still don't have a focused window.
550 */
551void InputDispatcher::processNoFocusedWindowAnrLocked() {
552 // Check if the application that we are waiting for is still focused.
553 std::shared_ptr<InputApplicationHandle> focusedApplication =
554 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
555 if (focusedApplication == nullptr ||
556 focusedApplication->getApplicationToken() !=
557 mAwaitedFocusedApplication->getApplicationToken()) {
558 // Unexpected because we should have reset the ANR timer when focused application changed
559 ALOGE("Waited for a focused window, but focused application has already changed to %s",
560 focusedApplication->getName().c_str());
561 return; // The focused application has changed.
562 }
563
564 const sp<InputWindowHandle>& focusedWindowHandle =
565 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
566 if (focusedWindowHandle != nullptr) {
567 return; // We now have a focused window. No need for ANR.
568 }
569 onAnrLocked(mAwaitedFocusedApplication);
570}
571
572/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700573 * Check if any of the connections' wait queues have events that are too old.
574 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
575 * Return the time at which we should wake up next.
576 */
577nsecs_t InputDispatcher::processAnrsLocked() {
578 const nsecs_t currentTime = now();
579 nsecs_t nextAnrCheck = LONG_LONG_MAX;
580 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
581 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
582 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500583 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700584 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500585 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700586 return LONG_LONG_MIN;
587 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500588 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700589 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
590 }
591 }
592
593 // Check if any connection ANRs are due
594 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
595 if (currentTime < nextAnrCheck) { // most likely scenario
596 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
597 }
598
599 // If we reached here, we have an unresponsive connection.
600 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
601 if (connection == nullptr) {
602 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
603 return nextAnrCheck;
604 }
605 connection->responsive = false;
606 // Stop waking up for this unresponsive connection
607 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -0500608 onAnrLocked(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700609 return LONG_LONG_MIN;
610}
611
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500612std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700613 sp<InputWindowHandle> window = getWindowHandleLocked(token);
614 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500615 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700616 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500617 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700618}
619
Michael Wrightd02c5b62014-02-10 15:10:22 -0800620void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
621 nsecs_t currentTime = now();
622
Jeff Browndc5992e2014-04-11 01:27:26 -0700623 // Reset the key repeat timer whenever normal dispatch is suspended while the
624 // device is in a non-interactive state. This is to ensure that we abort a key
625 // repeat if the device is just coming out of sleep.
626 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800627 resetKeyRepeatLocked();
628 }
629
630 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
631 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100632 if (DEBUG_FOCUS) {
633 ALOGD("Dispatch frozen. Waiting some more.");
634 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800635 return;
636 }
637
638 // Optimize latency of app switches.
639 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
640 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
641 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
642 if (mAppSwitchDueTime < *nextWakeupTime) {
643 *nextWakeupTime = mAppSwitchDueTime;
644 }
645
646 // Ready to start a new event.
647 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700648 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700649 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800650 if (isAppSwitchDue) {
651 // The inbound queue is empty so the app switch key we were waiting
652 // for will never arrive. Stop waiting for it.
653 resetPendingAppSwitchLocked(false);
654 isAppSwitchDue = false;
655 }
656
657 // Synthesize a key repeat if appropriate.
658 if (mKeyRepeatState.lastKeyEntry) {
659 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
660 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
661 } else {
662 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
663 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
664 }
665 }
666 }
667
668 // Nothing to do if there is no pending event.
669 if (!mPendingEvent) {
670 return;
671 }
672 } else {
673 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700674 mPendingEvent = mInboundQueue.front();
675 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800676 traceInboundQueueLengthLocked();
677 }
678
679 // Poke user activity for this event.
680 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700681 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800682 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800683 }
684
685 // Now we have an event to dispatch.
686 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700687 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800688 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700689 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800690 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700691 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800692 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700693 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800694 }
695
696 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700697 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800698 }
699
700 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700701 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700702 const ConfigurationChangedEntry& typedEntry =
703 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700704 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700705 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700706 break;
707 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800708
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700709 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700710 const DeviceResetEntry& typedEntry =
711 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700712 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700713 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700714 break;
715 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800716
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100717 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700718 std::shared_ptr<FocusEntry> typedEntry =
719 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100720 dispatchFocusLocked(currentTime, typedEntry);
721 done = true;
722 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
723 break;
724 }
725
Prabir Pradhan99987712020-11-10 18:43:05 -0800726 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
727 const auto typedEntry =
728 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
729 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
730 done = true;
731 break;
732 }
733
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700734 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700735 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700736 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700737 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700738 resetPendingAppSwitchLocked(true);
739 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700740 } else if (dropReason == DropReason::NOT_DROPPED) {
741 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700742 }
743 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700744 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700745 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700746 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700747 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
748 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700749 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700750 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700751 break;
752 }
753
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700754 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700755 std::shared_ptr<MotionEntry> motionEntry =
756 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700757 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
758 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800759 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700760 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700761 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700762 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700763 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
764 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700765 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700766 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700767 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800768 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800769 }
770
771 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700772 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700773 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800774 }
Michael Wright3a981722015-06-10 15:26:13 +0100775 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800776
777 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700778 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800779 }
780}
781
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700782/**
783 * Return true if the events preceding this incoming motion event should be dropped
784 * Return false otherwise (the default behaviour)
785 */
786bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700787 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700788 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700789
790 // Optimize case where the current application is unresponsive and the user
791 // decides to touch a window in a different application.
792 // If the application takes too long to catch up then we drop all events preceding
793 // the touch into the other window.
794 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700795 int32_t displayId = motionEntry.displayId;
796 int32_t x = static_cast<int32_t>(
797 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
798 int32_t y = static_cast<int32_t>(
799 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
800 sp<InputWindowHandle> touchedWindowHandle =
801 findTouchedWindowAtLocked(displayId, x, y, nullptr);
802 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700803 touchedWindowHandle->getApplicationToken() !=
804 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700805 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700806 ALOGI("Pruning input queue because user touched a different application while waiting "
807 "for %s",
808 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700809 return true;
810 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700811
812 // Alternatively, maybe there's a gesture monitor that could handle this event
813 std::vector<TouchedMonitor> gestureMonitors =
814 findTouchedGestureMonitorsLocked(displayId, {});
815 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
816 sp<Connection> connection =
817 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000818 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700819 // This monitor could take more input. Drop all events preceding this
820 // event, so that gesture monitor could get a chance to receive the stream
821 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
822 "responsive gesture monitor that may handle the event",
823 mAwaitedFocusedApplication->getName().c_str());
824 return true;
825 }
826 }
827 }
828
829 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
830 // yet been processed by some connections, the dispatcher will wait for these motion
831 // events to be processed before dispatching the key event. This is because these motion events
832 // may cause a new window to be launched, which the user might expect to receive focus.
833 // To prevent waiting forever for such events, just send the key to the currently focused window
834 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
835 ALOGD("Received a new pointer down event, stop waiting for events to process and "
836 "just send the pending key event to the focused window.");
837 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700838 }
839 return false;
840}
841
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700842bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700843 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700844 mInboundQueue.push_back(std::move(newEntry));
845 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800846 traceInboundQueueLengthLocked();
847
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700848 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700849 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700850 // Optimize app switch latency.
851 // If the application takes too long to catch up then we drop all events preceding
852 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700853 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700854 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700855 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700856 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700857 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700858 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800859#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700860 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800861#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700862 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700863 mAppSwitchSawKeyDown = false;
864 needWake = true;
865 }
866 }
867 }
868 break;
869 }
870
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700871 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700872 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
873 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700874 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800875 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700876 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800877 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100878 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700879 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
880 break;
881 }
882 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -0800883 case EventEntry::Type::DEVICE_RESET:
884 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700885 // nothing to do
886 break;
887 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800888 }
889
890 return needWake;
891}
892
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700893void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700894 mRecentQueue.push_back(entry);
895 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700896 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800897 }
898}
899
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700900sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700901 int32_t y, TouchState* touchState,
902 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700903 bool addPortalWindows) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700904 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
905 LOG_ALWAYS_FATAL(
906 "Must provide a valid touch state if adding portal windows or outside targets");
907 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800908 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700909 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800910 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800911 const InputWindowInfo* windowInfo = windowHandle->getInfo();
912 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100913 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800914
915 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100916 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
917 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
918 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800919 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800920 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700921 if (portalToDisplayId != ADISPLAY_ID_NONE &&
922 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800923 if (addPortalWindows) {
924 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700925 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800926 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700927 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700928 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800929 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800930 // Found window.
931 return windowHandle;
932 }
933 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800934
Michael Wright44753b12020-07-08 13:48:11 +0100935 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700936 touchState->addOrUpdateWindow(windowHandle,
937 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
938 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800939 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800940 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800941 }
942 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700943 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800944}
945
Garfield Tane84e6f92019-08-29 17:28:41 -0700946std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700947 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000948 std::vector<TouchedMonitor> touchedMonitors;
949
950 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
951 addGestureMonitors(monitors, touchedMonitors);
952 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
953 const InputWindowInfo* windowInfo = portalWindow->getInfo();
954 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700955 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
956 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000957 }
958 return touchedMonitors;
959}
960
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700961void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800962 const char* reason;
963 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700964 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800965#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700966 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800967#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700968 reason = "inbound event was dropped because the policy consumed it";
969 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700970 case DropReason::DISABLED:
971 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700972 ALOGI("Dropped event because input dispatch is disabled.");
973 }
974 reason = "inbound event was dropped because input dispatch is disabled";
975 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700976 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700977 ALOGI("Dropped event because of pending overdue app switch.");
978 reason = "inbound event was dropped because of pending overdue app switch";
979 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700980 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700981 ALOGI("Dropped event because the current application is not responding and the user "
982 "has started interacting with a different application.");
983 reason = "inbound event was dropped because the current application is not responding "
984 "and the user has started interacting with a different application";
985 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700986 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700987 ALOGI("Dropped event because it is stale.");
988 reason = "inbound event was dropped because it is stale";
989 break;
Prabir Pradhan99987712020-11-10 18:43:05 -0800990 case DropReason::NO_POINTER_CAPTURE:
991 ALOGI("Dropped event because there is no window with Pointer Capture.");
992 reason = "inbound event was dropped because there is no window with Pointer Capture";
993 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700994 case DropReason::NOT_DROPPED: {
995 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700996 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700997 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800998 }
999
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001000 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001001 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001002 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1003 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001004 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001005 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001006 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001007 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1008 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001009 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1010 synthesizeCancelationEventsForAllConnectionsLocked(options);
1011 } else {
1012 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1013 synthesizeCancelationEventsForAllConnectionsLocked(options);
1014 }
1015 break;
1016 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001017 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1018 break;
1019 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001020 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001021 case EventEntry::Type::CONFIGURATION_CHANGED:
1022 case EventEntry::Type::DEVICE_RESET: {
1023 LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
1024 break;
1025 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001026 }
1027}
1028
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001029static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001030 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1031 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001032}
1033
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001034bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1035 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1036 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1037 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001038}
1039
1040bool InputDispatcher::isAppSwitchPendingLocked() {
1041 return mAppSwitchDueTime != LONG_LONG_MAX;
1042}
1043
1044void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1045 mAppSwitchDueTime = LONG_LONG_MAX;
1046
1047#if DEBUG_APP_SWITCH
1048 if (handled) {
1049 ALOGD("App switch has arrived.");
1050 } else {
1051 ALOGD("App switch was abandoned.");
1052 }
1053#endif
1054}
1055
Michael Wrightd02c5b62014-02-10 15:10:22 -08001056bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001057 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001058}
1059
1060bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001061 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001062 return false;
1063 }
1064
1065 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001066 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001067 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001068 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001069 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001070
1071 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001072 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001073 return true;
1074}
1075
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001076void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1077 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001078}
1079
1080void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001081 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001082 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001083 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001084 releaseInboundEventLocked(entry);
1085 }
1086 traceInboundQueueLengthLocked();
1087}
1088
1089void InputDispatcher::releasePendingEventLocked() {
1090 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001091 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001092 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001093 }
1094}
1095
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001096void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001097 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001098 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001099#if DEBUG_DISPATCH_CYCLE
1100 ALOGD("Injected inbound event was dropped.");
1101#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001102 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001103 }
1104 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001105 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001106 }
1107 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001108}
1109
1110void InputDispatcher::resetKeyRepeatLocked() {
1111 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001112 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001113 }
1114}
1115
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001116std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1117 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001118
Michael Wright2e732952014-09-24 13:26:59 -07001119 uint32_t policyFlags = entry->policyFlags &
1120 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001121
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001122 std::shared_ptr<KeyEntry> newEntry =
1123 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1124 entry->source, entry->displayId, policyFlags, entry->action,
1125 entry->flags, entry->keyCode, entry->scanCode,
1126 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001127
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001128 newEntry->syntheticRepeat = true;
1129 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001131 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001132}
1133
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001134bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001135 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001136#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001137 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001138#endif
1139
1140 // Reset key repeating in case a keyboard device was added or removed or something.
1141 resetKeyRepeatLocked();
1142
1143 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001144 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1145 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001146 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001147 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001148 return true;
1149}
1150
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001151bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1152 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001153#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001154 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1155 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001156#endif
1157
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001158 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001159 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001160 synthesizeCancelationEventsForAllConnectionsLocked(options);
1161 return true;
1162}
1163
Vishnu Nairad321cd2020-08-20 16:40:21 -07001164void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001165 std::string_view reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001166 if (mPendingEvent != nullptr) {
1167 // Move the pending event to the front of the queue. This will give the chance
1168 // for the pending event to get dispatched to the newly focused window
1169 mInboundQueue.push_front(mPendingEvent);
1170 mPendingEvent = nullptr;
1171 }
1172
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001173 std::unique_ptr<FocusEntry> focusEntry =
1174 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1175 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001176
1177 // This event should go to the front of the queue, but behind all other focus events
1178 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001179 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001180 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001181 [](const std::shared_ptr<EventEntry>& event) {
1182 return event->type == EventEntry::Type::FOCUS;
1183 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001184
1185 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001186 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001187}
1188
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001189void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001190 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001191 if (channel == nullptr) {
1192 return; // Window has gone away
1193 }
1194 InputTarget target;
1195 target.inputChannel = channel;
1196 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1197 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001198 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1199 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001200 std::string reason = std::string("reason=").append(entry->reason);
1201 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001202 dispatchEventLocked(currentTime, entry, {target});
1203}
1204
Prabir Pradhan99987712020-11-10 18:43:05 -08001205void InputDispatcher::dispatchPointerCaptureChangedLocked(
1206 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1207 DropReason& dropReason) {
1208 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
1209 if (entry->pointerCaptureEnabled == haveWindowWithPointerCapture) {
1210 LOG_ALWAYS_FATAL_IF(mFocusedWindowRequestedPointerCapture,
1211 "The Pointer Capture state has already been dispatched to the window.");
1212 // Pointer capture was already forcefully disabled because of focus change.
1213 dropReason = DropReason::NOT_DROPPED;
1214 return;
1215 }
1216
1217 // Set drop reason for early returns
1218 dropReason = DropReason::NO_POINTER_CAPTURE;
1219
1220 sp<IBinder> token;
1221 if (entry->pointerCaptureEnabled) {
1222 // Enable Pointer Capture
1223 if (!mFocusedWindowRequestedPointerCapture) {
1224 // This can happen if a window requests capture and immediately releases capture.
1225 ALOGW("No window requested Pointer Capture.");
1226 return;
1227 }
1228 token = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
1229 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1230 mWindowTokenWithPointerCapture = token;
1231 } else {
1232 // Disable Pointer Capture
1233 token = mWindowTokenWithPointerCapture;
1234 mWindowTokenWithPointerCapture = nullptr;
1235 mFocusedWindowRequestedPointerCapture = false;
1236 }
1237
1238 auto channel = getInputChannelLocked(token);
1239 if (channel == nullptr) {
1240 // Window has gone away, clean up Pointer Capture state.
1241 mWindowTokenWithPointerCapture = nullptr;
1242 mFocusedWindowRequestedPointerCapture = false;
1243 return;
1244 }
1245 InputTarget target;
1246 target.inputChannel = channel;
1247 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1248 entry->dispatchInProgress = true;
1249 dispatchEventLocked(currentTime, entry, {target});
1250
1251 dropReason = DropReason::NOT_DROPPED;
1252}
1253
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001254bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001255 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001256 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001257 if (!entry->dispatchInProgress) {
1258 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1259 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1260 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1261 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001262 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001263 // We have seen two identical key downs in a row which indicates that the device
1264 // driver is automatically generating key repeats itself. We take note of the
1265 // repeat here, but we disable our own next key repeat timer since it is clear that
1266 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001267 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1268 // Make sure we don't get key down from a different device. If a different
1269 // device Id has same key pressed down, the new device Id will replace the
1270 // current one to hold the key repeat with repeat count reset.
1271 // In the future when got a KEY_UP on the device id, drop it and do not
1272 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001273 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1274 resetKeyRepeatLocked();
1275 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1276 } else {
1277 // Not a repeat. Save key down state in case we do see a repeat later.
1278 resetKeyRepeatLocked();
1279 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1280 }
1281 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001282 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1283 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001284 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001285#if DEBUG_INBOUND_EVENT_DETAILS
1286 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1287#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001288 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001289 resetKeyRepeatLocked();
1290 }
1291
1292 if (entry->repeatCount == 1) {
1293 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1294 } else {
1295 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1296 }
1297
1298 entry->dispatchInProgress = true;
1299
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001300 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001301 }
1302
1303 // Handle case where the policy asked us to try again later last time.
1304 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1305 if (currentTime < entry->interceptKeyWakeupTime) {
1306 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1307 *nextWakeupTime = entry->interceptKeyWakeupTime;
1308 }
1309 return false; // wait until next wakeup
1310 }
1311 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1312 entry->interceptKeyWakeupTime = 0;
1313 }
1314
1315 // Give the policy a chance to intercept the key.
1316 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1317 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001318 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001319 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001320 sp<IBinder> focusedWindowToken =
1321 getValueByKey(mFocusedWindowTokenByDisplay, getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001322 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001323 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001324 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001325 return false; // wait for the command to run
1326 } else {
1327 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1328 }
1329 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001330 if (*dropReason == DropReason::NOT_DROPPED) {
1331 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001332 }
1333 }
1334
1335 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001336 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001337 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001338 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1339 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001340 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001341 return true;
1342 }
1343
1344 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001345 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001346 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001347 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001348 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001349 return false;
1350 }
1351
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001352 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001353 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001354 return true;
1355 }
1356
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001357 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001358 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001359
1360 // Dispatch the key.
1361 dispatchEventLocked(currentTime, entry, inputTargets);
1362 return true;
1363}
1364
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001365void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001366#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001367 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001368 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1369 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001370 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1371 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1372 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001373#endif
1374}
1375
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001376bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001377 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001378 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001379 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001380 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001381 entry->dispatchInProgress = true;
1382
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001383 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001384 }
1385
1386 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001387 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001388 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001389 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1390 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001391 return true;
1392 }
1393
1394 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1395
1396 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001397 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001398
1399 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001400 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001401 if (isPointerEvent) {
1402 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001403 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001404 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001405 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001406 } else {
1407 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001408 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001409 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001410 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001411 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001412 return false;
1413 }
1414
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001415 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001416 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001417 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1418 return true;
1419 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001420 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001421 CancelationOptions::Mode mode(isPointerEvent
1422 ? CancelationOptions::CANCEL_POINTER_EVENTS
1423 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1424 CancelationOptions options(mode, "input event injection failed");
1425 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001426 return true;
1427 }
1428
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001429 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001430 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001431
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001432 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001433 std::unordered_map<int32_t, TouchState>::iterator it =
1434 mTouchStatesByDisplay.find(entry->displayId);
1435 if (it != mTouchStatesByDisplay.end()) {
1436 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001437 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001438 // The event has gone through these portal windows, so we add monitoring targets of
1439 // the corresponding displays as well.
1440 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001441 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001442 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001443 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001444 }
1445 }
1446 }
1447 }
1448
Michael Wrightd02c5b62014-02-10 15:10:22 -08001449 // Dispatch the motion.
1450 if (conflictingPointerActions) {
1451 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001452 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001453 synthesizeCancelationEventsForAllConnectionsLocked(options);
1454 }
1455 dispatchEventLocked(currentTime, entry, inputTargets);
1456 return true;
1457}
1458
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001459void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001460#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001461 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001462 ", policyFlags=0x%x, "
1463 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1464 "metaState=0x%x, buttonState=0x%x,"
1465 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001466 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1467 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1468 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001469
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001470 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001471 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001472 "x=%f, y=%f, pressure=%f, size=%f, "
1473 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1474 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001475 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1476 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1477 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1478 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1479 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1480 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1481 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1482 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1483 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1484 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001485 }
1486#endif
1487}
1488
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001489void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1490 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001491 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001492 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001493#if DEBUG_DISPATCH_CYCLE
1494 ALOGD("dispatchEventToCurrentInputTargets");
1495#endif
1496
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001497 updateInteractionTokensLocked(*eventEntry, inputTargets);
1498
Michael Wrightd02c5b62014-02-10 15:10:22 -08001499 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1500
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001501 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001502
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001503 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001504 sp<Connection> connection =
1505 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001506 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001507 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001508 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001509 if (DEBUG_FOCUS) {
1510 ALOGD("Dropping event delivery to target with channel '%s' because it "
1511 "is no longer registered with the input dispatcher.",
1512 inputTarget.inputChannel->getName().c_str());
1513 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001514 }
1515 }
1516}
1517
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001518void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1519 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1520 // If the policy decides to close the app, we will get a channel removal event via
1521 // unregisterInputChannel, and will clean up the connection that way. We are already not
1522 // sending new pointers to the connection when it blocked, but focused events will continue to
1523 // pile up.
1524 ALOGW("Canceling events for %s because it is unresponsive",
1525 connection->inputChannel->getName().c_str());
1526 if (connection->status == Connection::STATUS_NORMAL) {
1527 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1528 "application not responding");
1529 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001530 }
1531}
1532
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001533void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001534 if (DEBUG_FOCUS) {
1535 ALOGD("Resetting ANR timeouts.");
1536 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001537
1538 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001539 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001540 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001541}
1542
Tiger Huang721e26f2018-07-24 22:26:19 +08001543/**
1544 * Get the display id that the given event should go to. If this event specifies a valid display id,
1545 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1546 * Focused display is the display that the user most recently interacted with.
1547 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001548int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001549 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001550 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001551 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001552 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1553 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001554 break;
1555 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001556 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001557 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1558 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001559 break;
1560 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001561 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001562 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001563 case EventEntry::Type::CONFIGURATION_CHANGED:
1564 case EventEntry::Type::DEVICE_RESET: {
1565 ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001566 return ADISPLAY_ID_NONE;
1567 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001568 }
1569 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1570}
1571
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001572bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1573 const char* focusedWindowName) {
1574 if (mAnrTracker.empty()) {
1575 // already processed all events that we waited for
1576 mKeyIsWaitingForEventsTimeout = std::nullopt;
1577 return false;
1578 }
1579
1580 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1581 // Start the timer
1582 ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
1583 "focus to change",
1584 focusedWindowName);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001585 mKeyIsWaitingForEventsTimeout = currentTime +
1586 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1587 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001588 return true;
1589 }
1590
1591 // We still have pending events, and already started the timer
1592 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1593 return true; // Still waiting
1594 }
1595
1596 // Waited too long, and some connection still hasn't processed all motions
1597 // Just send the key to the focused window
1598 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1599 focusedWindowName);
1600 mKeyIsWaitingForEventsTimeout = std::nullopt;
1601 return false;
1602}
1603
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001604InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1605 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1606 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001607 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001608
Tiger Huang721e26f2018-07-24 22:26:19 +08001609 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001610 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001611 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001612 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1613
Michael Wrightd02c5b62014-02-10 15:10:22 -08001614 // If there is no currently focused window and no focused application
1615 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001616 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1617 ALOGI("Dropping %s event because there is no focused window or focused application in "
1618 "display %" PRId32 ".",
1619 EventEntry::typeToString(entry.type), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001620 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001621 }
1622
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001623 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1624 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1625 // start interacting with another application via touch (app switch). This code can be removed
1626 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1627 // an app is expected to have a focused window.
1628 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1629 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1630 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001631 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1632 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1633 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001634 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001635 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001636 ALOGW("Waiting because no window has focus but %s may eventually add a "
1637 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001638 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001639 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001640 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001641 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1642 // Already raised ANR. Drop the event
1643 ALOGE("Dropping %s event because there is no focused window",
1644 EventEntry::typeToString(entry.type));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001645 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001646 } else {
1647 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001648 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001649 }
1650 }
1651
1652 // we have a valid, non-null focused window
1653 resetNoFocusedWindowTimeoutLocked();
1654
Michael Wrightd02c5b62014-02-10 15:10:22 -08001655 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001656 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001657 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001658 }
1659
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001660 if (focusedWindowHandle->getInfo()->paused) {
1661 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001662 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001663 }
1664
1665 // If the event is a key event, then we must wait for all previous events to
1666 // complete before delivering it because previous events may have the
1667 // side-effect of transferring focus to a different window and we want to
1668 // ensure that the following keys are sent to the new window.
1669 //
1670 // Suppose the user touches a button in a window then immediately presses "A".
1671 // If the button causes a pop-up window to appear then we want to ensure that
1672 // the "A" key is delivered to the new pop-up window. This is because users
1673 // often anticipate pending UI changes when typing on a keyboard.
1674 // To obtain this behavior, we must serialize key events with respect to all
1675 // prior input events.
1676 if (entry.type == EventEntry::Type::KEY) {
1677 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1678 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001679 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001680 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001681 }
1682
1683 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001684 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001685 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1686 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001687
1688 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001689 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001690}
1691
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001692/**
1693 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1694 * that are currently unresponsive.
1695 */
1696std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1697 const std::vector<TouchedMonitor>& monitors) const {
1698 std::vector<TouchedMonitor> responsiveMonitors;
1699 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1700 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1701 sp<Connection> connection = getConnectionLocked(
1702 monitor.monitor.inputChannel->getConnectionToken());
1703 if (connection == nullptr) {
1704 ALOGE("Could not find connection for monitor %s",
1705 monitor.monitor.inputChannel->getName().c_str());
1706 return false;
1707 }
1708 if (!connection->responsive) {
1709 ALOGW("Unresponsive monitor %s will not get the new gesture",
1710 connection->inputChannel->getName().c_str());
1711 return false;
1712 }
1713 return true;
1714 });
1715 return responsiveMonitors;
1716}
1717
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001718InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1719 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1720 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001721 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001722 enum InjectionPermission {
1723 INJECTION_PERMISSION_UNKNOWN,
1724 INJECTION_PERMISSION_GRANTED,
1725 INJECTION_PERMISSION_DENIED
1726 };
1727
Michael Wrightd02c5b62014-02-10 15:10:22 -08001728 // For security reasons, we defer updating the touch state until we are sure that
1729 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001730 int32_t displayId = entry.displayId;
1731 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001732 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1733
1734 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001735 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001736 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001737 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1738 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001739
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001740 // Copy current touch state into tempTouchState.
1741 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1742 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001743 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001744 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001745 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1746 mTouchStatesByDisplay.find(displayId);
1747 if (oldStateIt != mTouchStatesByDisplay.end()) {
1748 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001749 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001750 }
1751
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001752 bool isSplit = tempTouchState.split;
1753 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1754 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1755 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001756 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1757 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1758 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1759 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1760 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001761 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001762 bool wrongDevice = false;
1763 if (newGesture) {
1764 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001765 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001766 ALOGI("Dropping event because a pointer for a different device is already down "
1767 "in display %" PRId32,
1768 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001769 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001770 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001771 switchedDevice = false;
1772 wrongDevice = true;
1773 goto Failed;
1774 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001775 tempTouchState.reset();
1776 tempTouchState.down = down;
1777 tempTouchState.deviceId = entry.deviceId;
1778 tempTouchState.source = entry.source;
1779 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001780 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001781 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001782 ALOGI("Dropping move event because a pointer for a different device is already active "
1783 "in display %" PRId32,
1784 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001785 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001786 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001787 switchedDevice = false;
1788 wrongDevice = true;
1789 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001790 }
1791
1792 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1793 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1794
Garfield Tan00f511d2019-06-12 16:55:40 -07001795 int32_t x;
1796 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001797 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001798 // Always dispatch mouse events to cursor position.
1799 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001800 x = int32_t(entry.xCursorPosition);
1801 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001802 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001803 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1804 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001805 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001806 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001807 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001808 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1809 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001810
1811 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001812 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001813 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001814
Michael Wrightd02c5b62014-02-10 15:10:22 -08001815 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001816 if (newTouchedWindowHandle != nullptr &&
1817 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001818 // New window supports splitting, but we should never split mouse events.
1819 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001820 } else if (isSplit) {
1821 // New window does not support splitting but we have already split events.
1822 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001823 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001824 }
1825
1826 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001827 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001828 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001829 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001830 }
1831
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001832 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1833 ALOGI("Not sending touch event to %s because it is paused",
1834 newTouchedWindowHandle->getName().c_str());
1835 newTouchedWindowHandle = nullptr;
1836 }
1837
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001838 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001839 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001840 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1841 if (!isResponsive) {
1842 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001843 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1844 newTouchedWindowHandle = nullptr;
1845 }
1846 }
1847
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001848 // Drop events that can't be trusted due to occlusion
1849 if (newTouchedWindowHandle != nullptr &&
1850 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1851 TouchOcclusionInfo occlusionInfo =
1852 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001853 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001854 if (DEBUG_TOUCH_OCCLUSION) {
1855 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1856 for (const auto& log : occlusionInfo.debugInfo) {
1857 ALOGD("%s", log.c_str());
1858 }
1859 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001860 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
1861 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1862 ALOGW("Dropping untrusted touch event due to %s/%d",
1863 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1864 newTouchedWindowHandle = nullptr;
1865 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001866 }
1867 }
1868
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001869 // Also don't send the new touch event to unresponsive gesture monitors
1870 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1871
Michael Wright3dd60e22019-03-27 22:06:44 +00001872 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1873 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001874 "(%d, %d) in display %" PRId32 ".",
1875 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001876 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001877 goto Failed;
1878 }
1879
1880 if (newTouchedWindowHandle != nullptr) {
1881 // Set target flags.
1882 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1883 if (isSplit) {
1884 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001885 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001886 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1887 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1888 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1889 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1890 }
1891
1892 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07001893 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
1894 newHoverWindowHandle = nullptr;
1895 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001896 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00001897 }
1898
1899 // Update the temporary touch state.
1900 BitSet32 pointerIds;
1901 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001902 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001903 pointerIds.markBit(pointerId);
1904 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001905 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001906 }
1907
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001908 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001909 } else {
1910 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1911
1912 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001913 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001914 if (DEBUG_FOCUS) {
1915 ALOGD("Dropping event because the pointer is not down or we previously "
1916 "dropped the pointer down event in display %" PRId32,
1917 displayId);
1918 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001919 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920 goto Failed;
1921 }
1922
1923 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001924 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001925 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001926 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1927 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001928
1929 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001930 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07001931 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001932 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1933 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001934 if (DEBUG_FOCUS) {
1935 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
1936 oldTouchedWindowHandle->getName().c_str(),
1937 newTouchedWindowHandle->getName().c_str(), displayId);
1938 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001939 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001940 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1941 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1942 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001943
1944 // Make a slippery entrance into the new window.
1945 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1946 isSplit = true;
1947 }
1948
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001949 int32_t targetFlags =
1950 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001951 if (isSplit) {
1952 targetFlags |= InputTarget::FLAG_SPLIT;
1953 }
1954 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1955 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10001956 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1957 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001958 }
1959
1960 BitSet32 pointerIds;
1961 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001962 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001963 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001964 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001965 }
1966 }
1967 }
1968
1969 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07001970 // Let the previous window know that the hover sequence is over, unless we already did it
1971 // when dispatching it as is to newTouchedWindowHandle.
1972 if (mLastHoverWindowHandle != nullptr &&
1973 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
1974 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001975#if DEBUG_HOVER
1976 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001977 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001978#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001979 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1980 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001981 }
1982
Garfield Tandf26e862020-07-01 20:18:19 -07001983 // Let the new window know that the hover sequence is starting, unless we already did it
1984 // when dispatching it as is to newTouchedWindowHandle.
1985 if (newHoverWindowHandle != nullptr &&
1986 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
1987 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001988#if DEBUG_HOVER
1989 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001990 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001991#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001992 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1993 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1994 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001995 }
1996 }
1997
1998 // Check permission to inject into all touched foreground windows and ensure there
1999 // is at least one touched foreground window.
2000 {
2001 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002002 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002003 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2004 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002005 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002006 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002007 injectionPermission = INJECTION_PERMISSION_DENIED;
2008 goto Failed;
2009 }
2010 }
2011 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002012 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002013 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002014 ALOGI("Dropping event because there is no touched foreground window in display "
2015 "%" PRId32 " or gesture monitor to receive it.",
2016 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002017 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002018 goto Failed;
2019 }
2020
2021 // Permission granted to injection into all touched foreground windows.
2022 injectionPermission = INJECTION_PERMISSION_GRANTED;
2023 }
2024
2025 // Check whether windows listening for outside touches are owned by the same UID. If it is
2026 // set the policy flag that we will not reveal coordinate information to this window.
2027 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2028 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002029 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002030 if (foregroundWindowHandle) {
2031 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002032 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002033 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2034 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
2035 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002036 tempTouchState.addOrUpdateWindow(inputWindowHandle,
2037 InputTarget::FLAG_ZERO_COORDS,
2038 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002039 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002040 }
2041 }
2042 }
2043 }
2044
Michael Wrightd02c5b62014-02-10 15:10:22 -08002045 // If this is the first pointer going down and the touched window has a wallpaper
2046 // then also add the touched wallpaper windows so they are locked in for the duration
2047 // of the touch gesture.
2048 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2049 // engine only supports touch events. We would need to add a mechanism similar
2050 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2051 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2052 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002053 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002054 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07002055 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002056 getWindowHandlesLocked(displayId);
2057 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002058 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002059 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01002060 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002061 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002062 .addOrUpdateWindow(windowHandle,
2063 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2064 InputTarget::
2065 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2066 InputTarget::FLAG_DISPATCH_AS_IS,
2067 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002068 }
2069 }
2070 }
2071 }
2072
2073 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002074 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002075
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002076 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002077 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002078 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002079 }
2080
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002081 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002082 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002083 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002084 }
2085
Michael Wrightd02c5b62014-02-10 15:10:22 -08002086 // Drop the outside or hover touch windows since we will not care about them
2087 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002088 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002089
2090Failed:
2091 // Check injection permission once and for all.
2092 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002093 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002094 injectionPermission = INJECTION_PERMISSION_GRANTED;
2095 } else {
2096 injectionPermission = INJECTION_PERMISSION_DENIED;
2097 }
2098 }
2099
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002100 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2101 return injectionResult;
2102 }
2103
Michael Wrightd02c5b62014-02-10 15:10:22 -08002104 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002105 if (!wrongDevice) {
2106 if (switchedDevice) {
2107 if (DEBUG_FOCUS) {
2108 ALOGD("Conflicting pointer actions: Switched to a different device.");
2109 }
2110 *outConflictingPointerActions = true;
2111 }
2112
2113 if (isHoverAction) {
2114 // Started hovering, therefore no longer down.
2115 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002116 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002117 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2118 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002119 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002120 *outConflictingPointerActions = true;
2121 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002122 tempTouchState.reset();
2123 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2124 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2125 tempTouchState.deviceId = entry.deviceId;
2126 tempTouchState.source = entry.source;
2127 tempTouchState.displayId = displayId;
2128 }
2129 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2130 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2131 // All pointers up or canceled.
2132 tempTouchState.reset();
2133 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2134 // First pointer went down.
2135 if (oldState && oldState->down) {
2136 if (DEBUG_FOCUS) {
2137 ALOGD("Conflicting pointer actions: Down received while already down.");
2138 }
2139 *outConflictingPointerActions = true;
2140 }
2141 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2142 // One pointer went up.
2143 if (isSplit) {
2144 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2145 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002146
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002147 for (size_t i = 0; i < tempTouchState.windows.size();) {
2148 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2149 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2150 touchedWindow.pointerIds.clearBit(pointerId);
2151 if (touchedWindow.pointerIds.isEmpty()) {
2152 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2153 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002154 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002155 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002156 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002157 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002158 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002159 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002160
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002161 // Save changes unless the action was scroll in which case the temporary touch
2162 // state was only valid for this one action.
2163 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2164 if (tempTouchState.displayId >= 0) {
2165 mTouchStatesByDisplay[displayId] = tempTouchState;
2166 } else {
2167 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002168 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002169 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002170
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002171 // Update hover state.
2172 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002173 }
2174
Michael Wrightd02c5b62014-02-10 15:10:22 -08002175 return injectionResult;
2176}
2177
2178void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002179 int32_t targetFlags, BitSet32 pointerIds,
2180 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002181 std::vector<InputTarget>::iterator it =
2182 std::find_if(inputTargets.begin(), inputTargets.end(),
2183 [&windowHandle](const InputTarget& inputTarget) {
2184 return inputTarget.inputChannel->getConnectionToken() ==
2185 windowHandle->getToken();
2186 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002187
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002188 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002189
2190 if (it == inputTargets.end()) {
2191 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002192 std::shared_ptr<InputChannel> inputChannel =
2193 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002194 if (inputChannel == nullptr) {
2195 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2196 return;
2197 }
2198 inputTarget.inputChannel = inputChannel;
2199 inputTarget.flags = targetFlags;
2200 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2201 inputTargets.push_back(inputTarget);
2202 it = inputTargets.end() - 1;
2203 }
2204
2205 ALOG_ASSERT(it->flags == targetFlags);
2206 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2207
chaviw1ff3d1e2020-07-01 15:53:47 -07002208 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002209}
2210
Michael Wright3dd60e22019-03-27 22:06:44 +00002211void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002212 int32_t displayId, float xOffset,
2213 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002214 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2215 mGlobalMonitorsByDisplay.find(displayId);
2216
2217 if (it != mGlobalMonitorsByDisplay.end()) {
2218 const std::vector<Monitor>& monitors = it->second;
2219 for (const Monitor& monitor : monitors) {
2220 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002221 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002222 }
2223}
2224
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002225void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2226 float yOffset,
2227 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002228 InputTarget target;
2229 target.inputChannel = monitor.inputChannel;
2230 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002231 ui::Transform t;
2232 t.set(xOffset, yOffset);
2233 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002234 inputTargets.push_back(target);
2235}
2236
Michael Wrightd02c5b62014-02-10 15:10:22 -08002237bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002238 const InjectionState* injectionState) {
2239 if (injectionState &&
2240 (windowHandle == nullptr ||
2241 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2242 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002243 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002244 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002245 "owned by uid %d",
2246 injectionState->injectorPid, injectionState->injectorUid,
2247 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002248 } else {
2249 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002250 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002251 }
2252 return false;
2253 }
2254 return true;
2255}
2256
Robert Carrc9bf1d32020-04-13 17:21:08 -07002257/**
2258 * Indicate whether one window handle should be considered as obscuring
2259 * another window handle. We only check a few preconditions. Actually
2260 * checking the bounds is left to the caller.
2261 */
2262static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2263 const sp<InputWindowHandle>& otherHandle) {
2264 // Compare by token so cloned layers aren't counted
2265 if (haveSameToken(windowHandle, otherHandle)) {
2266 return false;
2267 }
2268 auto info = windowHandle->getInfo();
2269 auto otherInfo = otherHandle->getInfo();
2270 if (!otherInfo->visible) {
2271 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002272 } else if (otherInfo->alpha == 0 &&
2273 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2274 // Those act as if they were invisible, so we don't need to flag them.
2275 // We do want to potentially flag touchable windows even if they have 0
2276 // opacity, since they can consume touches and alter the effects of the
2277 // user interaction (eg. apps that rely on
2278 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2279 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2280 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002281 } else if (info->ownerUid == otherInfo->ownerUid) {
2282 // If ownerUid is the same we don't generate occlusion events as there
2283 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002284 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002285 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002286 return false;
2287 } else if (otherInfo->displayId != info->displayId) {
2288 return false;
2289 }
2290 return true;
2291}
2292
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002293/**
2294 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2295 * untrusted, one should check:
2296 *
2297 * 1. If result.hasBlockingOcclusion is true.
2298 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2299 * BLOCK_UNTRUSTED.
2300 *
2301 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2302 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2303 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2304 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2305 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2306 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2307 *
2308 * If neither of those is true, then it means the touch can be allowed.
2309 */
2310InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2311 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002312 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2313 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002314 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2315 TouchOcclusionInfo info;
2316 info.hasBlockingOcclusion = false;
2317 info.obscuringOpacity = 0;
2318 info.obscuringUid = -1;
2319 std::map<int32_t, float> opacityByUid;
2320 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2321 if (windowHandle == otherHandle) {
2322 break; // All future windows are below us. Exit early.
2323 }
2324 const InputWindowInfo* otherInfo = otherHandle->getInfo();
2325 if (canBeObscuredBy(windowHandle, otherHandle) &&
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002326 windowInfo->ownerUid != otherInfo->ownerUid && otherInfo->frameContainsPoint(x, y)) {
2327 if (DEBUG_TOUCH_OCCLUSION) {
2328 info.debugInfo.push_back(
2329 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2330 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002331 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2332 // we perform the checks below to see if the touch can be propagated or not based on the
2333 // window's touch occlusion mode
2334 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2335 info.hasBlockingOcclusion = true;
2336 info.obscuringUid = otherInfo->ownerUid;
2337 info.obscuringPackage = otherInfo->packageName;
2338 break;
2339 }
2340 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2341 uint32_t uid = otherInfo->ownerUid;
2342 float opacity =
2343 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2344 // Given windows A and B:
2345 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2346 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2347 opacityByUid[uid] = opacity;
2348 if (opacity > info.obscuringOpacity) {
2349 info.obscuringOpacity = opacity;
2350 info.obscuringUid = uid;
2351 info.obscuringPackage = otherInfo->packageName;
2352 }
2353 }
2354 }
2355 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002356 if (DEBUG_TOUCH_OCCLUSION) {
2357 info.debugInfo.push_back(
2358 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2359 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002360 return info;
2361}
2362
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002363std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2364 bool isTouchedWindow) const {
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002365 return StringPrintf(INDENT2 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32
2366 ", mode=%s, alpha=%.2f, "
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002367 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2368 "], touchableRegion=%s, window={%s}, applicationInfo=%s, "
2369 "flags={%s}, inputFeatures={%s}, hasToken=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002370 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002371 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002372 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002373 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2374 info->frameTop, info->frameRight, info->frameBottom,
2375 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002376 info->applicationInfo.name.c_str(), info->flags.string().c_str(),
2377 info->inputFeatures.string().c_str(), toString(info->token != nullptr));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002378}
2379
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002380bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2381 if (occlusionInfo.hasBlockingOcclusion) {
2382 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2383 occlusionInfo.obscuringUid);
2384 return false;
2385 }
2386 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2387 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2388 "%.2f, maximum allowed = %.2f)",
2389 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2390 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2391 return false;
2392 }
2393 return true;
2394}
2395
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002396bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2397 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002398 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002399 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002400 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002401 if (windowHandle == otherHandle) {
2402 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002403 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002404 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002405 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002406 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002407 return true;
2408 }
2409 }
2410 return false;
2411}
2412
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002413bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2414 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002415 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002416 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002417 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002418 if (windowHandle == otherHandle) {
2419 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002420 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002421 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002422 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002423 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002424 return true;
2425 }
2426 }
2427 return false;
2428}
2429
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002430std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002431 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002432 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002433 if (applicationHandle != nullptr) {
2434 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002435 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002436 } else {
2437 return applicationHandle->getName();
2438 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002439 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002440 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002441 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002442 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002443 }
2444}
2445
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002446void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002447 if (eventEntry.type == EventEntry::Type::FOCUS ||
2448 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED) {
2449 // Focus or pointer capture changed events are passed to apps, but do not represent user
2450 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002451 return;
2452 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002453 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002454 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002455 if (focusedWindowHandle != nullptr) {
2456 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002457 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002458#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002459 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002460#endif
2461 return;
2462 }
2463 }
2464
2465 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002466 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002467 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002468 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2469 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002470 return;
2471 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002472
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002473 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002474 eventType = USER_ACTIVITY_EVENT_TOUCH;
2475 }
2476 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002477 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002478 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002479 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2480 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002481 return;
2482 }
2483 eventType = USER_ACTIVITY_EVENT_BUTTON;
2484 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002485 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002486 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002487 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002488 case EventEntry::Type::DEVICE_RESET:
2489 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002490 LOG_ALWAYS_FATAL("%s events are not user activity",
2491 EventEntry::typeToString(eventEntry.type));
2492 break;
2493 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002494 }
2495
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002496 std::unique_ptr<CommandEntry> commandEntry =
2497 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002498 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002499 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002500 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002501}
2502
2503void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002504 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002505 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002506 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002507 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002508 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002509 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002510 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002511 ATRACE_NAME(message.c_str());
2512 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002513#if DEBUG_DISPATCH_CYCLE
2514 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002515 "globalScaleFactor=%f, pointerIds=0x%x %s",
2516 connection->getInputChannelName().c_str(), inputTarget.flags,
2517 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2518 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002519#endif
2520
2521 // Skip this event if the connection status is not normal.
2522 // We don't want to enqueue additional outbound events if the connection is broken.
2523 if (connection->status != Connection::STATUS_NORMAL) {
2524#if DEBUG_DISPATCH_CYCLE
2525 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002526 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002527#endif
2528 return;
2529 }
2530
2531 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002532 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2533 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2534 "Entry type %s should not have FLAG_SPLIT",
2535 EventEntry::typeToString(eventEntry->type));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002536
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002537 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002538 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002539 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002540 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002541 if (!splitMotionEntry) {
2542 return; // split event was dropped
2543 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002544 if (DEBUG_FOCUS) {
2545 ALOGD("channel '%s' ~ Split motion event.",
2546 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002547 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002548 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002549 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2550 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002551 return;
2552 }
2553 }
2554
2555 // Not splitting. Enqueue dispatch entries for the event as is.
2556 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2557}
2558
2559void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002560 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002561 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002562 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002563 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002564 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002565 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002566 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002567 ATRACE_NAME(message.c_str());
2568 }
2569
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002570 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002571
2572 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002573 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002574 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002575 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002576 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002577 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002578 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002579 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002580 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002581 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002582 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002583 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002584 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002585
2586 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002587 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002588 startDispatchCycleLocked(currentTime, connection);
2589 }
2590}
2591
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002592void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002593 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002594 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002595 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002596 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002597 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2598 connection->getInputChannelName().c_str(),
2599 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002600 ATRACE_NAME(message.c_str());
2601 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002602 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002603 if (!(inputTargetFlags & dispatchMode)) {
2604 return;
2605 }
2606 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2607
2608 // This is a new event.
2609 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002610 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002611 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002612
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002613 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2614 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002615 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002616 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002617 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002618 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002619 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002620 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002621 dispatchEntry->resolvedAction = keyEntry.action;
2622 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002623
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002624 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2625 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002626#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002627 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2628 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002629#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002630 return; // skip the inconsistent event
2631 }
2632 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002633 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002634
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002635 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002636 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002637 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2638 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2639 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2640 static_cast<int32_t>(IdGenerator::Source::OTHER);
2641 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002642 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2643 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2644 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2645 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2646 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2647 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2648 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2649 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2650 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2651 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2652 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002653 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002654 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002655 }
2656 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002657 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2658 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002659#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002660 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2661 "event",
2662 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002663#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002664 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2665 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002666
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002667 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002668 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2669 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2670 }
2671 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2672 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2673 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002674
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002675 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2676 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002677#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002678 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2679 "event",
2680 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002681#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002682 return; // skip the inconsistent event
2683 }
2684
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002685 dispatchEntry->resolvedEventId =
2686 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2687 ? mIdGenerator.nextId()
2688 : motionEntry.id;
2689 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2690 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2691 ") to MotionEvent(id=0x%" PRIx32 ").",
2692 motionEntry.id, dispatchEntry->resolvedEventId);
2693 ATRACE_NAME(message.c_str());
2694 }
2695
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002696 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002697 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002698
2699 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002700 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002701 case EventEntry::Type::FOCUS:
2702 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002703 break;
2704 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002705 case EventEntry::Type::CONFIGURATION_CHANGED:
2706 case EventEntry::Type::DEVICE_RESET: {
2707 LOG_ALWAYS_FATAL("%s events should not go to apps",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002708 EventEntry::typeToString(newEntry.type));
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002709 break;
2710 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002711 }
2712
2713 // Remember that we are waiting for this dispatch to complete.
2714 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002715 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002716 }
2717
2718 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002719 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002720 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002721}
2722
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002723/**
2724 * This function is purely for debugging. It helps us understand where the user interaction
2725 * was taking place. For example, if user is touching launcher, we will see a log that user
2726 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2727 * We will see both launcher and wallpaper in that list.
2728 * Once the interaction with a particular set of connections starts, no new logs will be printed
2729 * until the set of interacted connections changes.
2730 *
2731 * The following items are skipped, to reduce the logspam:
2732 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2733 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2734 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2735 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2736 * Both of those ACTION_UP events would not be logged
2737 * Monitors (both gesture and global): any gesture monitors or global monitors receiving events
2738 * will not be logged. This is omitted to reduce the amount of data printed.
2739 * If you see <none>, it's likely that one of the gesture monitors pilfered the event, and therefore
2740 * gesture monitor is the only connection receiving the remainder of the gesture.
2741 */
2742void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2743 const std::vector<InputTarget>& targets) {
2744 // Skip ACTION_UP events, and all events other than keys and motions
2745 if (entry.type == EventEntry::Type::KEY) {
2746 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2747 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2748 return;
2749 }
2750 } else if (entry.type == EventEntry::Type::MOTION) {
2751 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2752 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2753 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2754 return;
2755 }
2756 } else {
2757 return; // Not a key or a motion
2758 }
2759
2760 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2761 std::vector<sp<Connection>> newConnections;
2762 for (const InputTarget& target : targets) {
2763 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2764 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2765 continue; // Skip windows that receive ACTION_OUTSIDE
2766 }
2767
2768 sp<IBinder> token = target.inputChannel->getConnectionToken();
2769 sp<Connection> connection = getConnectionLocked(token);
2770 if (connection == nullptr || connection->monitor) {
2771 continue; // We only need to keep track of the non-monitor connections.
2772 }
2773 newConnectionTokens.insert(std::move(token));
2774 newConnections.emplace_back(connection);
2775 }
2776 if (newConnectionTokens == mInteractionConnectionTokens) {
2777 return; // no change
2778 }
2779 mInteractionConnectionTokens = newConnectionTokens;
2780
2781 std::string windowList;
2782 for (const sp<Connection>& connection : newConnections) {
2783 windowList += connection->getWindowName() + ", ";
2784 }
2785 std::string message = "Interaction with windows: " + windowList;
2786 if (windowList.empty()) {
2787 message += "<none>";
2788 }
2789 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2790}
2791
chaviwfd6d3512019-03-25 13:23:49 -07002792void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002793 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002794 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002795 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2796 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002797 return;
2798 }
2799
Vishnu Nairad321cd2020-08-20 16:40:21 -07002800 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
2801 if (focusedToken == token) {
2802 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002803 return;
2804 }
2805
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002806 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2807 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002808 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002809 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002810}
2811
2812void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002813 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002814 if (ATRACE_ENABLED()) {
2815 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002816 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002817 ATRACE_NAME(message.c_str());
2818 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002819#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002820 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002821#endif
2822
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002823 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2824 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002825 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002826 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002827 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002828 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002829
2830 // Publish the event.
2831 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002832 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
2833 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002834 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002835 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2836 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002837
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002838 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002839 status = connection->inputPublisher
2840 .publishKeyEvent(dispatchEntry->seq,
2841 dispatchEntry->resolvedEventId, keyEntry.deviceId,
2842 keyEntry.source, keyEntry.displayId,
2843 std::move(hmac), dispatchEntry->resolvedAction,
2844 dispatchEntry->resolvedFlags, keyEntry.keyCode,
2845 keyEntry.scanCode, keyEntry.metaState,
2846 keyEntry.repeatCount, keyEntry.downTime,
2847 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002848 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002849 }
2850
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002851 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002852 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002853
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002854 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002855 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002856
chaviw82357092020-01-28 13:13:06 -08002857 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002858 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002859 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2860 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002861 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002862 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
2863 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002864 // Don't apply window scale here since we don't want scale to affect raw
2865 // coordinates. The scale will be sent back to the client and applied
2866 // later when requesting relative coordinates.
2867 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2868 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002869 }
2870 usingCoords = scaledCoords;
2871 }
2872 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002873 // We don't want the dispatch target to know.
2874 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002875 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002876 scaledCoords[i].clear();
2877 }
2878 usingCoords = scaledCoords;
2879 }
2880 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002881
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002882 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002883
2884 // Publish the motion event.
2885 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002886 .publishMotionEvent(dispatchEntry->seq,
2887 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002888 motionEntry.deviceId, motionEntry.source,
2889 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002890 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002891 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002892 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002893 motionEntry.edgeFlags, motionEntry.metaState,
2894 motionEntry.buttonState,
2895 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07002896 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002897 motionEntry.xPrecision, motionEntry.yPrecision,
2898 motionEntry.xCursorPosition,
2899 motionEntry.yCursorPosition,
2900 motionEntry.downTime, motionEntry.eventTime,
2901 motionEntry.pointerCount,
2902 motionEntry.pointerProperties, usingCoords);
2903 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002904 break;
2905 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002906
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002907 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002908 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002909 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002910 focusEntry.id,
2911 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002912 mInTouchMode);
2913 break;
2914 }
2915
Prabir Pradhan99987712020-11-10 18:43:05 -08002916 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
2917 const auto& captureEntry =
2918 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
2919 status = connection->inputPublisher
2920 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
2921 captureEntry.pointerCaptureEnabled);
2922 break;
2923 }
2924
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002925 case EventEntry::Type::CONFIGURATION_CHANGED:
2926 case EventEntry::Type::DEVICE_RESET: {
2927 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002928 EventEntry::typeToString(eventEntry.type));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002929 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08002930 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002931 }
2932
2933 // Check the result.
2934 if (status) {
2935 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002936 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002937 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002938 "This is unexpected because the wait queue is empty, so the pipe "
2939 "should be empty and we shouldn't have any problems writing an "
2940 "event to it, status=%d",
2941 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002942 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2943 } else {
2944 // Pipe is full and we are waiting for the app to finish process some events
2945 // before sending more events to it.
2946#if DEBUG_DISPATCH_CYCLE
2947 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002948 "waiting for the application to catch up",
2949 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002950#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08002951 }
2952 } else {
2953 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002954 "status=%d",
2955 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002956 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2957 }
2958 return;
2959 }
2960
2961 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002962 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2963 connection->outboundQueue.end(),
2964 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002965 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002966 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002967 if (connection->responsive) {
2968 mAnrTracker.insert(dispatchEntry->timeoutTime,
2969 connection->inputChannel->getConnectionToken());
2970 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002971 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002972 }
2973}
2974
chaviw09c8d2d2020-08-24 15:48:26 -07002975std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
2976 size_t size;
2977 switch (event.type) {
2978 case VerifiedInputEvent::Type::KEY: {
2979 size = sizeof(VerifiedKeyEvent);
2980 break;
2981 }
2982 case VerifiedInputEvent::Type::MOTION: {
2983 size = sizeof(VerifiedMotionEvent);
2984 break;
2985 }
2986 }
2987 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
2988 return mHmacKeyManager.sign(start, size);
2989}
2990
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002991const std::array<uint8_t, 32> InputDispatcher::getSignature(
2992 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
2993 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
2994 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
2995 // Only sign events up and down events as the purely move events
2996 // are tied to their up/down counterparts so signing would be redundant.
2997 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
2998 verifiedEvent.actionMasked = actionMasked;
2999 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003000 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003001 }
3002 return INVALID_HMAC;
3003}
3004
3005const std::array<uint8_t, 32> InputDispatcher::getSignature(
3006 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3007 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3008 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3009 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003010 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003011}
3012
Michael Wrightd02c5b62014-02-10 15:10:22 -08003013void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003014 const sp<Connection>& connection, uint32_t seq,
3015 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003016#if DEBUG_DISPATCH_CYCLE
3017 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003018 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003019#endif
3020
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003021 if (connection->status == Connection::STATUS_BROKEN ||
3022 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003023 return;
3024 }
3025
3026 // Notify other system components and prepare to start the next dispatch cycle.
3027 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
3028}
3029
3030void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003031 const sp<Connection>& connection,
3032 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003033#if DEBUG_DISPATCH_CYCLE
3034 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003035 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003036#endif
3037
3038 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003039 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003040 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003041 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003042 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003043
3044 // The connection appears to be unrecoverably broken.
3045 // Ignore already broken or zombie connections.
3046 if (connection->status == Connection::STATUS_NORMAL) {
3047 connection->status = Connection::STATUS_BROKEN;
3048
3049 if (notify) {
3050 // Notify other system components.
3051 onDispatchCycleBrokenLocked(currentTime, connection);
3052 }
3053 }
3054}
3055
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003056void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3057 while (!queue.empty()) {
3058 DispatchEntry* dispatchEntry = queue.front();
3059 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003060 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003061 }
3062}
3063
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003064void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003065 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003066 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003067 }
3068 delete dispatchEntry;
3069}
3070
3071int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
3072 InputDispatcher* d = static_cast<InputDispatcher*>(data);
3073
3074 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003075 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003076
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003077 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003078 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003079 "fd=%d, events=0x%x",
3080 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003081 return 0; // remove the callback
3082 }
3083
3084 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003085 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003086 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3087 if (!(events & ALOOPER_EVENT_INPUT)) {
3088 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003089 "events=0x%x",
3090 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003091 return 1;
3092 }
3093
3094 nsecs_t currentTime = now();
3095 bool gotOne = false;
3096 status_t status;
3097 for (;;) {
3098 uint32_t seq;
3099 bool handled;
3100 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
3101 if (status) {
3102 break;
3103 }
3104 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
3105 gotOne = true;
3106 }
3107 if (gotOne) {
3108 d->runCommandsLockedInterruptible();
3109 if (status == WOULD_BLOCK) {
3110 return 1;
3111 }
3112 }
3113
3114 notify = status != DEAD_OBJECT || !connection->monitor;
3115 if (notify) {
3116 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003117 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003118 }
3119 } else {
3120 // Monitor channels are never explicitly unregistered.
3121 // We do it automatically when the remote endpoint is closed so don't warn
3122 // about them.
arthurhungd352cb32020-04-28 17:09:28 +08003123 const bool stillHaveWindowHandle =
3124 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3125 nullptr;
3126 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003127 if (notify) {
3128 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003129 "events=0x%x",
3130 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003131 }
3132 }
3133
Garfield Tan15601662020-09-22 15:32:38 -07003134 // Remove the channel.
3135 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003136 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003137 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003138}
3139
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003140void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003141 const CancelationOptions& options) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003142 for (const auto& [fd, connection] : mConnectionsByFd) {
3143 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003144 }
3145}
3146
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003147void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003148 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003149 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3150 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3151}
3152
3153void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3154 const CancelationOptions& options,
3155 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3156 for (const auto& it : monitorsByDisplay) {
3157 const std::vector<Monitor>& monitors = it.second;
3158 for (const Monitor& monitor : monitors) {
3159 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003160 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003161 }
3162}
3163
Michael Wrightd02c5b62014-02-10 15:10:22 -08003164void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003165 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003166 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003167 if (connection == nullptr) {
3168 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003169 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003170
3171 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003172}
3173
3174void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3175 const sp<Connection>& connection, const CancelationOptions& options) {
3176 if (connection->status == Connection::STATUS_BROKEN) {
3177 return;
3178 }
3179
3180 nsecs_t currentTime = now();
3181
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003182 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003183 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003184
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003185 if (cancelationEvents.empty()) {
3186 return;
3187 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003188#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003189 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3190 "with reality: %s, mode=%d.",
3191 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3192 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003193#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003194
3195 InputTarget target;
3196 sp<InputWindowHandle> windowHandle =
3197 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3198 if (windowHandle != nullptr) {
3199 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003200 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003201 target.globalScaleFactor = windowInfo->globalScaleFactor;
3202 }
3203 target.inputChannel = connection->inputChannel;
3204 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3205
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003206 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003207 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003208 switch (cancelationEventEntry->type) {
3209 case EventEntry::Type::KEY: {
3210 logOutboundKeyDetails("cancel - ",
3211 static_cast<const KeyEntry&>(*cancelationEventEntry));
3212 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003213 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003214 case EventEntry::Type::MOTION: {
3215 logOutboundMotionDetails("cancel - ",
3216 static_cast<const MotionEntry&>(*cancelationEventEntry));
3217 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003218 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003219 case EventEntry::Type::FOCUS:
3220 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3221 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
3222 EventEntry::typeToString(cancelationEventEntry->type));
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003223 break;
3224 }
3225 case EventEntry::Type::CONFIGURATION_CHANGED:
3226 case EventEntry::Type::DEVICE_RESET: {
3227 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3228 EventEntry::typeToString(cancelationEventEntry->type));
3229 break;
3230 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003231 }
3232
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003233 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3234 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003235 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003236
3237 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003238}
3239
Svet Ganov5d3bc372020-01-26 23:11:07 -08003240void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3241 const sp<Connection>& connection) {
3242 if (connection->status == Connection::STATUS_BROKEN) {
3243 return;
3244 }
3245
3246 nsecs_t currentTime = now();
3247
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003248 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003249 connection->inputState.synthesizePointerDownEvents(currentTime);
3250
3251 if (downEvents.empty()) {
3252 return;
3253 }
3254
3255#if DEBUG_OUTBOUND_EVENT_DETAILS
3256 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3257 connection->getInputChannelName().c_str(), downEvents.size());
3258#endif
3259
3260 InputTarget target;
3261 sp<InputWindowHandle> windowHandle =
3262 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3263 if (windowHandle != nullptr) {
3264 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003265 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003266 target.globalScaleFactor = windowInfo->globalScaleFactor;
3267 }
3268 target.inputChannel = connection->inputChannel;
3269 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3270
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003271 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003272 switch (downEventEntry->type) {
3273 case EventEntry::Type::MOTION: {
3274 logOutboundMotionDetails("down - ",
3275 static_cast<const MotionEntry&>(*downEventEntry));
3276 break;
3277 }
3278
3279 case EventEntry::Type::KEY:
3280 case EventEntry::Type::FOCUS:
3281 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003282 case EventEntry::Type::DEVICE_RESET:
3283 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003284 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
3285 EventEntry::typeToString(downEventEntry->type));
3286 break;
3287 }
3288 }
3289
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003290 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3291 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003292 }
3293
3294 startDispatchCycleLocked(currentTime, connection);
3295}
3296
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003297std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3298 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003299 ALOG_ASSERT(pointerIds.value != 0);
3300
3301 uint32_t splitPointerIndexMap[MAX_POINTERS];
3302 PointerProperties splitPointerProperties[MAX_POINTERS];
3303 PointerCoords splitPointerCoords[MAX_POINTERS];
3304
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003305 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003306 uint32_t splitPointerCount = 0;
3307
3308 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003309 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003310 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003311 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003312 uint32_t pointerId = uint32_t(pointerProperties.id);
3313 if (pointerIds.hasBit(pointerId)) {
3314 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3315 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3316 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003317 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318 splitPointerCount += 1;
3319 }
3320 }
3321
3322 if (splitPointerCount != pointerIds.count()) {
3323 // This is bad. We are missing some of the pointers that we expected to deliver.
3324 // Most likely this indicates that we received an ACTION_MOVE events that has
3325 // different pointer ids than we expected based on the previous ACTION_DOWN
3326 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3327 // in this way.
3328 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003329 "we expected there to be %d pointers. This probably means we received "
3330 "a broken sequence of pointer ids from the input device.",
3331 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003332 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003333 }
3334
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003335 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003336 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003337 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3338 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003339 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3340 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003341 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003342 uint32_t pointerId = uint32_t(pointerProperties.id);
3343 if (pointerIds.hasBit(pointerId)) {
3344 if (pointerIds.count() == 1) {
3345 // The first/last pointer went down/up.
3346 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003347 ? AMOTION_EVENT_ACTION_DOWN
3348 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003349 } else {
3350 // A secondary pointer went down/up.
3351 uint32_t splitPointerIndex = 0;
3352 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3353 splitPointerIndex += 1;
3354 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003355 action = maskedAction |
3356 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003357 }
3358 } else {
3359 // An unrelated pointer changed.
3360 action = AMOTION_EVENT_ACTION_MOVE;
3361 }
3362 }
3363
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003364 int32_t newId = mIdGenerator.nextId();
3365 if (ATRACE_ENABLED()) {
3366 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3367 ") to MotionEvent(id=0x%" PRIx32 ").",
3368 originalMotionEntry.id, newId);
3369 ATRACE_NAME(message.c_str());
3370 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003371 std::unique_ptr<MotionEntry> splitMotionEntry =
3372 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3373 originalMotionEntry.deviceId, originalMotionEntry.source,
3374 originalMotionEntry.displayId,
3375 originalMotionEntry.policyFlags, action,
3376 originalMotionEntry.actionButton,
3377 originalMotionEntry.flags, originalMotionEntry.metaState,
3378 originalMotionEntry.buttonState,
3379 originalMotionEntry.classification,
3380 originalMotionEntry.edgeFlags,
3381 originalMotionEntry.xPrecision,
3382 originalMotionEntry.yPrecision,
3383 originalMotionEntry.xCursorPosition,
3384 originalMotionEntry.yCursorPosition,
3385 originalMotionEntry.downTime, splitPointerCount,
3386 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003387
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003388 if (originalMotionEntry.injectionState) {
3389 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003390 splitMotionEntry->injectionState->refCount += 1;
3391 }
3392
3393 return splitMotionEntry;
3394}
3395
3396void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3397#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003398 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003399#endif
3400
3401 bool needWake;
3402 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003403 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003404
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003405 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3406 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3407 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003408 } // release lock
3409
3410 if (needWake) {
3411 mLooper->wake();
3412 }
3413}
3414
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003415/**
3416 * If one of the meta shortcuts is detected, process them here:
3417 * Meta + Backspace -> generate BACK
3418 * Meta + Enter -> generate HOME
3419 * This will potentially overwrite keyCode and metaState.
3420 */
3421void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003422 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003423 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3424 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3425 if (keyCode == AKEYCODE_DEL) {
3426 newKeyCode = AKEYCODE_BACK;
3427 } else if (keyCode == AKEYCODE_ENTER) {
3428 newKeyCode = AKEYCODE_HOME;
3429 }
3430 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003431 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003432 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003433 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003434 keyCode = newKeyCode;
3435 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3436 }
3437 } else if (action == AKEY_EVENT_ACTION_UP) {
3438 // In order to maintain a consistent stream of up and down events, check to see if the key
3439 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3440 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003441 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003442 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003443 auto replacementIt = mReplacedKeys.find(replacement);
3444 if (replacementIt != mReplacedKeys.end()) {
3445 keyCode = replacementIt->second;
3446 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003447 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3448 }
3449 }
3450}
3451
Michael Wrightd02c5b62014-02-10 15:10:22 -08003452void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3453#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003454 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3455 "policyFlags=0x%x, action=0x%x, "
3456 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3457 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3458 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3459 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003460#endif
3461 if (!validateKeyEvent(args->action)) {
3462 return;
3463 }
3464
3465 uint32_t policyFlags = args->policyFlags;
3466 int32_t flags = args->flags;
3467 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003468 // InputDispatcher tracks and generates key repeats on behalf of
3469 // whatever notifies it, so repeatCount should always be set to 0
3470 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003471 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3472 policyFlags |= POLICY_FLAG_VIRTUAL;
3473 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3474 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003475 if (policyFlags & POLICY_FLAG_FUNCTION) {
3476 metaState |= AMETA_FUNCTION_ON;
3477 }
3478
3479 policyFlags |= POLICY_FLAG_TRUSTED;
3480
Michael Wright78f24442014-08-06 15:55:28 -07003481 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003482 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003483
Michael Wrightd02c5b62014-02-10 15:10:22 -08003484 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003485 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003486 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3487 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003488
Michael Wright2b3c3302018-03-02 17:19:13 +00003489 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003490 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003491 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3492 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003493 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003494 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003495
Michael Wrightd02c5b62014-02-10 15:10:22 -08003496 bool needWake;
3497 { // acquire lock
3498 mLock.lock();
3499
3500 if (shouldSendKeyToInputFilterLocked(args)) {
3501 mLock.unlock();
3502
3503 policyFlags |= POLICY_FLAG_FILTERED;
3504 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3505 return; // event was consumed by the filter
3506 }
3507
3508 mLock.lock();
3509 }
3510
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003511 std::unique_ptr<KeyEntry> newEntry =
3512 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3513 args->displayId, policyFlags, args->action, flags,
3514 keyCode, args->scanCode, metaState, repeatCount,
3515 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003516
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003517 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003518 mLock.unlock();
3519 } // release lock
3520
3521 if (needWake) {
3522 mLooper->wake();
3523 }
3524}
3525
3526bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3527 return mInputFilterEnabled;
3528}
3529
3530void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3531#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003532 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3533 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003534 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3535 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003536 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003537 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3538 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3539 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3540 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003541 for (uint32_t i = 0; i < args->pointerCount; i++) {
3542 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003543 "x=%f, y=%f, pressure=%f, size=%f, "
3544 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3545 "orientation=%f",
3546 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3547 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3548 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3549 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3550 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3551 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3552 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3553 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3554 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3555 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003556 }
3557#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003558 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3559 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003560 return;
3561 }
3562
3563 uint32_t policyFlags = args->policyFlags;
3564 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003565
3566 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003567 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003568 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3569 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003570 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003571 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003572
3573 bool needWake;
3574 { // acquire lock
3575 mLock.lock();
3576
3577 if (shouldSendMotionToInputFilterLocked(args)) {
3578 mLock.unlock();
3579
3580 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003581 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003582 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3583 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003584 args->metaState, args->buttonState, args->classification, transform,
3585 args->xPrecision, args->yPrecision, args->xCursorPosition,
3586 args->yCursorPosition, args->downTime, args->eventTime,
3587 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003588
3589 policyFlags |= POLICY_FLAG_FILTERED;
3590 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3591 return; // event was consumed by the filter
3592 }
3593
3594 mLock.lock();
3595 }
3596
3597 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003598 std::unique_ptr<MotionEntry> newEntry =
3599 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3600 args->source, args->displayId, policyFlags,
3601 args->action, args->actionButton, args->flags,
3602 args->metaState, args->buttonState,
3603 args->classification, args->edgeFlags,
3604 args->xPrecision, args->yPrecision,
3605 args->xCursorPosition, args->yCursorPosition,
3606 args->downTime, args->pointerCount,
3607 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003608
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003609 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003610 mLock.unlock();
3611 } // release lock
3612
3613 if (needWake) {
3614 mLooper->wake();
3615 }
3616}
3617
3618bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003619 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003620}
3621
3622void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3623#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003624 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003625 "switchMask=0x%08x",
3626 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003627#endif
3628
3629 uint32_t policyFlags = args->policyFlags;
3630 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003631 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003632}
3633
3634void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3635#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003636 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3637 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003638#endif
3639
3640 bool needWake;
3641 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003642 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003643
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003644 std::unique_ptr<DeviceResetEntry> newEntry =
3645 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3646 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003647 } // release lock
3648
3649 if (needWake) {
3650 mLooper->wake();
3651 }
3652}
3653
Prabir Pradhan7e186182020-11-10 13:56:45 -08003654void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3655#if DEBUG_INBOUND_EVENT_DETAILS
3656 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3657 args->enabled ? "true" : "false");
3658#endif
3659
Prabir Pradhan99987712020-11-10 18:43:05 -08003660 bool needWake;
3661 { // acquire lock
3662 std::scoped_lock _l(mLock);
3663 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
3664 args->enabled);
3665 needWake = enqueueInboundEventLocked(std::move(entry));
3666 } // release lock
3667
3668 if (needWake) {
3669 mLooper->wake();
3670 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003671}
3672
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003673InputEventInjectionResult InputDispatcher::injectInputEvent(
3674 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3675 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003676#if DEBUG_INBOUND_EVENT_DETAILS
3677 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003678 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3679 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003680#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003681 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003682
3683 policyFlags |= POLICY_FLAG_INJECTED;
3684 if (hasInjectionPermission(injectorPid, injectorUid)) {
3685 policyFlags |= POLICY_FLAG_TRUSTED;
3686 }
3687
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003688 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003689 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003690 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003691 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3692 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003693 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003694 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003695 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003696
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003697 int32_t flags = incomingKey.getFlags();
3698 int32_t keyCode = incomingKey.getKeyCode();
3699 int32_t metaState = incomingKey.getMetaState();
3700 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003701 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003702 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003703 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003704 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3705 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3706 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003707
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003708 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3709 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003710 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003711
3712 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3713 android::base::Timer t;
3714 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3715 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3716 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3717 std::to_string(t.duration().count()).c_str());
3718 }
3719 }
3720
3721 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003722 std::unique_ptr<KeyEntry> injectedEntry =
3723 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3724 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3725 incomingKey.getDisplayId(), policyFlags, action,
3726 flags, keyCode, incomingKey.getScanCode(), metaState,
3727 incomingKey.getRepeatCount(),
3728 incomingKey.getDownTime());
3729 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003730 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003731 }
3732
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003733 case AINPUT_EVENT_TYPE_MOTION: {
3734 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3735 int32_t action = motionEvent->getAction();
3736 size_t pointerCount = motionEvent->getPointerCount();
3737 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3738 int32_t actionButton = motionEvent->getActionButton();
3739 int32_t displayId = motionEvent->getDisplayId();
3740 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003741 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003742 }
3743
3744 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3745 nsecs_t eventTime = motionEvent->getEventTime();
3746 android::base::Timer t;
3747 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3748 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3749 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3750 std::to_string(t.duration().count()).c_str());
3751 }
3752 }
3753
3754 mLock.lock();
3755 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3756 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003757 std::unique_ptr<MotionEntry> injectedEntry =
3758 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3759 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3760 motionEvent->getDisplayId(), policyFlags, action,
3761 actionButton, motionEvent->getFlags(),
3762 motionEvent->getMetaState(),
3763 motionEvent->getButtonState(),
3764 motionEvent->getClassification(),
3765 motionEvent->getEdgeFlags(),
3766 motionEvent->getXPrecision(),
3767 motionEvent->getYPrecision(),
3768 motionEvent->getRawXCursorPosition(),
3769 motionEvent->getRawYCursorPosition(),
3770 motionEvent->getDownTime(),
3771 uint32_t(pointerCount), pointerProperties,
3772 samplePointerCoords, motionEvent->getXOffset(),
3773 motionEvent->getYOffset());
3774 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003775 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3776 sampleEventTimes += 1;
3777 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003778 std::unique_ptr<MotionEntry> nextInjectedEntry =
3779 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3780 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3781 motionEvent->getDisplayId(), policyFlags,
3782 action, actionButton, motionEvent->getFlags(),
3783 motionEvent->getMetaState(),
3784 motionEvent->getButtonState(),
3785 motionEvent->getClassification(),
3786 motionEvent->getEdgeFlags(),
3787 motionEvent->getXPrecision(),
3788 motionEvent->getYPrecision(),
3789 motionEvent->getRawXCursorPosition(),
3790 motionEvent->getRawYCursorPosition(),
3791 motionEvent->getDownTime(),
3792 uint32_t(pointerCount), pointerProperties,
3793 samplePointerCoords,
3794 motionEvent->getXOffset(),
3795 motionEvent->getYOffset());
3796 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003797 }
3798 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003799 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003800
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003801 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003802 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003803 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003804 }
3805
3806 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003807 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003808 injectionState->injectionIsAsync = true;
3809 }
3810
3811 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003812 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003813
3814 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003815 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003816 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003817 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003818 }
3819
3820 mLock.unlock();
3821
3822 if (needWake) {
3823 mLooper->wake();
3824 }
3825
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003826 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003827 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003828 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003829
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003830 if (syncMode == InputEventInjectionSync::NONE) {
3831 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003832 } else {
3833 for (;;) {
3834 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003835 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003836 break;
3837 }
3838
3839 nsecs_t remainingTimeout = endTime - now();
3840 if (remainingTimeout <= 0) {
3841#if DEBUG_INJECTION
3842 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003843 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003844#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003845 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003846 break;
3847 }
3848
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003849 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003850 }
3851
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003852 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3853 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003854 while (injectionState->pendingForegroundDispatches != 0) {
3855#if DEBUG_INJECTION
3856 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003857 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003858#endif
3859 nsecs_t remainingTimeout = endTime - now();
3860 if (remainingTimeout <= 0) {
3861#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003862 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3863 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003864#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003865 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003866 break;
3867 }
3868
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003869 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003870 }
3871 }
3872 }
3873
3874 injectionState->release();
3875 } // release lock
3876
3877#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003878 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003879 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003880#endif
3881
3882 return injectionResult;
3883}
3884
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003885std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05003886 std::array<uint8_t, 32> calculatedHmac;
3887 std::unique_ptr<VerifiedInputEvent> result;
3888 switch (event.getType()) {
3889 case AINPUT_EVENT_TYPE_KEY: {
3890 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
3891 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
3892 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003893 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05003894 break;
3895 }
3896 case AINPUT_EVENT_TYPE_MOTION: {
3897 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
3898 VerifiedMotionEvent verifiedMotionEvent =
3899 verifiedMotionEventFromMotionEvent(motionEvent);
3900 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07003901 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05003902 break;
3903 }
3904 default: {
3905 ALOGE("Cannot verify events of type %" PRId32, event.getType());
3906 return nullptr;
3907 }
3908 }
3909 if (calculatedHmac == INVALID_HMAC) {
3910 return nullptr;
3911 }
3912 if (calculatedHmac != event.getHmac()) {
3913 return nullptr;
3914 }
3915 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003916}
3917
Michael Wrightd02c5b62014-02-10 15:10:22 -08003918bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003919 return injectorUid == 0 ||
3920 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003921}
3922
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003923void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003924 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003925 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003926 if (injectionState) {
3927#if DEBUG_INJECTION
3928 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003929 "injectorPid=%d, injectorUid=%d",
3930 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003931#endif
3932
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003933 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003934 // Log the outcome since the injector did not wait for the injection result.
3935 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003936 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003937 ALOGV("Asynchronous input event injection succeeded.");
3938 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003939 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003940 ALOGW("Asynchronous input event injection failed.");
3941 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003942 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003943 ALOGW("Asynchronous input event injection permission denied.");
3944 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003945 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003946 ALOGW("Asynchronous input event injection timed out.");
3947 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003948 case InputEventInjectionResult::PENDING:
3949 ALOGE("Setting result to 'PENDING' for asynchronous injection");
3950 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003951 }
3952 }
3953
3954 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003955 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003956 }
3957}
3958
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003959void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
3960 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003961 if (injectionState) {
3962 injectionState->pendingForegroundDispatches += 1;
3963 }
3964}
3965
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003966void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
3967 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003968 if (injectionState) {
3969 injectionState->pendingForegroundDispatches -= 1;
3970
3971 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003972 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003973 }
3974 }
3975}
3976
Vishnu Nairad321cd2020-08-20 16:40:21 -07003977const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003978 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003979 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
3980 auto it = mWindowHandlesByDisplay.find(displayId);
3981 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08003982}
3983
Michael Wrightd02c5b62014-02-10 15:10:22 -08003984sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003985 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08003986 if (windowHandleToken == nullptr) {
3987 return nullptr;
3988 }
3989
Arthur Hungb92218b2018-08-14 12:00:21 +08003990 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07003991 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003992 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003993 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003994 return windowHandle;
3995 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003996 }
3997 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003998 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003999}
4000
Vishnu Nairad321cd2020-08-20 16:40:21 -07004001sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4002 int displayId) const {
4003 if (windowHandleToken == nullptr) {
4004 return nullptr;
4005 }
4006
4007 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
4008 if (windowHandle->getToken() == windowHandleToken) {
4009 return windowHandle;
4010 }
4011 }
4012 return nullptr;
4013}
4014
4015sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
4016 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4017 return getWindowHandleLocked(focusedToken, displayId);
4018}
4019
Mady Mellor017bcd12020-06-23 19:12:00 +00004020bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
4021 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004022 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00004023 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004024 if (handle->getId() == windowHandle->getId() &&
4025 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004026 if (windowHandle->getInfo()->displayId != it.first) {
4027 ALOGE("Found window %s in display %" PRId32
4028 ", but it should belong to display %" PRId32,
4029 windowHandle->getName().c_str(), it.first,
4030 windowHandle->getInfo()->displayId);
4031 }
4032 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08004033 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004034 }
4035 }
4036 return false;
4037}
4038
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004039bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
4040 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4041 const bool noInputChannel =
4042 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4043 if (connection != nullptr && noInputChannel) {
4044 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4045 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4046 return false;
4047 }
4048
4049 if (connection == nullptr) {
4050 if (!noInputChannel) {
4051 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4052 }
4053 return false;
4054 }
4055 if (!connection->responsive) {
4056 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4057 return false;
4058 }
4059 return true;
4060}
4061
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004062std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4063 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07004064 size_t count = mInputChannelsByToken.count(token);
4065 if (count == 0) {
4066 return nullptr;
4067 }
4068 return mInputChannelsByToken.at(token);
4069}
4070
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004071void InputDispatcher::updateWindowHandlesForDisplayLocked(
4072 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
4073 if (inputWindowHandles.empty()) {
4074 // Remove all handles on a display if there are no windows left.
4075 mWindowHandlesByDisplay.erase(displayId);
4076 return;
4077 }
4078
4079 // Since we compare the pointer of input window handles across window updates, we need
4080 // to make sure the handle object for the same window stays unchanged across updates.
4081 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07004082 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004083 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004084 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004085 }
4086
4087 std::vector<sp<InputWindowHandle>> newHandles;
4088 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
4089 if (!handle->updateInfo()) {
4090 // handle no longer valid
4091 continue;
4092 }
4093
4094 const InputWindowInfo* info = handle->getInfo();
4095 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4096 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4097 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01004098 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4099 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
4100 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004101 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004102 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004103 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004104 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004105 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004106 }
4107
4108 if (info->displayId != displayId) {
4109 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4110 handle->getName().c_str(), displayId, info->displayId);
4111 continue;
4112 }
4113
Robert Carredd13602020-04-13 17:24:34 -07004114 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4115 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004116 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004117 oldHandle->updateFrom(handle);
4118 newHandles.push_back(oldHandle);
4119 } else {
4120 newHandles.push_back(handle);
4121 }
4122 }
4123
4124 // Insert or replace
4125 mWindowHandlesByDisplay[displayId] = newHandles;
4126}
4127
Arthur Hung72d8dc32020-03-28 00:48:39 +00004128void InputDispatcher::setInputWindows(
4129 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4130 { // acquire lock
4131 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004132 for (const auto& [displayId, handles] : handlesPerDisplay) {
4133 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004134 }
4135 }
4136 // Wake up poll loop since it may need to make new input dispatching choices.
4137 mLooper->wake();
4138}
4139
Arthur Hungb92218b2018-08-14 12:00:21 +08004140/**
4141 * Called from InputManagerService, update window handle list by displayId that can receive input.
4142 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4143 * If set an empty list, remove all handles from the specific display.
4144 * For focused handle, check if need to change and send a cancel event to previous one.
4145 * For removed handle, check if need to send a cancel event if already in touch.
4146 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004147void InputDispatcher::setInputWindowsLocked(
4148 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004149 if (DEBUG_FOCUS) {
4150 std::string windowList;
4151 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4152 windowList += iwh->getName() + " ";
4153 }
4154 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4155 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004156
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004157 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4158 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4159 const bool noInputWindow =
4160 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4161 if (noInputWindow && window->getToken() != nullptr) {
4162 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4163 window->getName().c_str());
4164 window->releaseChannel();
4165 }
4166 }
4167
Arthur Hung72d8dc32020-03-28 00:48:39 +00004168 // Copy old handles for release if they are no longer present.
4169 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004170
Arthur Hung72d8dc32020-03-28 00:48:39 +00004171 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004172
Vishnu Nair958da932020-08-21 17:12:37 -07004173 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4174 if (mLastHoverWindowHandle &&
4175 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4176 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004177 mLastHoverWindowHandle = nullptr;
4178 }
4179
Vishnu Nair958da932020-08-21 17:12:37 -07004180 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4181 if (focusedToken) {
4182 FocusResult result = checkTokenFocusableLocked(focusedToken, displayId);
4183 if (result != FocusResult::OK) {
4184 onFocusChangedLocked(focusedToken, nullptr, displayId, typeToString(result));
4185 }
4186 }
4187
4188 std::optional<FocusRequest> focusRequest =
4189 getOptionalValueByKey(mPendingFocusRequests, displayId);
4190 if (focusRequest) {
4191 // If the window from the pending request is now visible, provide it focus.
4192 FocusResult result = handleFocusRequestLocked(*focusRequest);
4193 if (result != FocusResult::NOT_VISIBLE) {
4194 // Drop the request if we were able to change the focus or we cannot change
4195 // it for another reason.
4196 mPendingFocusRequests.erase(displayId);
4197 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004198 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004199
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004200 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4201 mTouchStatesByDisplay.find(displayId);
4202 if (stateIt != mTouchStatesByDisplay.end()) {
4203 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004204 for (size_t i = 0; i < state.windows.size();) {
4205 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004206 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004207 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004208 ALOGD("Touched window was removed: %s in display %" PRId32,
4209 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004210 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004211 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004212 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4213 if (touchedInputChannel != nullptr) {
4214 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4215 "touched window was removed");
4216 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004217 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004218 state.windows.erase(state.windows.begin() + i);
4219 } else {
4220 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004221 }
4222 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004223 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004224
Arthur Hung72d8dc32020-03-28 00:48:39 +00004225 // Release information for windows that are no longer present.
4226 // This ensures that unused input channels are released promptly.
4227 // Otherwise, they might stick around until the window handle is destroyed
4228 // which might not happen until the next GC.
4229 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004230 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004231 if (DEBUG_FOCUS) {
4232 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004233 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004234 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004235 // To avoid making too many calls into the compat framework, only
4236 // check for window flags when windows are going away.
4237 // TODO(b/157929241) : delete this. This is only needed temporarily
4238 // in order to gather some data about the flag usage
4239 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4240 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4241 oldWindowHandle->getName().c_str());
4242 if (mCompatService != nullptr) {
4243 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4244 oldWindowHandle->getInfo()->ownerUid);
4245 }
4246 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004247 }
chaviw291d88a2019-02-14 10:33:58 -08004248 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004249}
4250
4251void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004252 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004253 if (DEBUG_FOCUS) {
4254 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4255 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4256 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004257 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004258 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004259
Chris Yea209fde2020-07-22 13:54:51 -07004260 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004261 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004262
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004263 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4264 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004265 }
4266
Chris Yea209fde2020-07-22 13:54:51 -07004267 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004268 if (inputApplicationHandle != nullptr) {
4269 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4270 } else {
4271 mFocusedApplicationHandlesByDisplay.erase(displayId);
4272 }
4273
4274 // No matter what the old focused application was, stop waiting on it because it is
4275 // no longer focused.
4276 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004277 } // release lock
4278
4279 // Wake up poll loop since it may need to make new input dispatching choices.
4280 mLooper->wake();
4281}
4282
Tiger Huang721e26f2018-07-24 22:26:19 +08004283/**
4284 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4285 * the display not specified.
4286 *
4287 * We track any unreleased events for each window. If a window loses the ability to receive the
4288 * released event, we will send a cancel event to it. So when the focused display is changed, we
4289 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4290 * display. The display-specified events won't be affected.
4291 */
4292void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004293 if (DEBUG_FOCUS) {
4294 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4295 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004296 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004297 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004298
4299 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004300 sp<IBinder> oldFocusedWindowToken =
4301 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4302 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004303 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004304 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004305 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004306 CancelationOptions
4307 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4308 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004309 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004310 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4311 }
4312 }
4313 mFocusedDisplayId = displayId;
4314
Chris Ye3c2d6f52020-08-09 10:39:48 -07004315 // Find new focused window and validate
Vishnu Nairad321cd2020-08-20 16:40:21 -07004316 sp<IBinder> newFocusedWindowToken =
4317 getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4318 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004319
Vishnu Nairad321cd2020-08-20 16:40:21 -07004320 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004321 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004322 if (!mFocusedWindowTokenByDisplay.empty()) {
4323 ALOGE("But another display has a focused window\n%s",
4324 dumpFocusedWindowsLocked().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004325 }
4326 }
4327 }
4328
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004329 if (DEBUG_FOCUS) {
4330 logDispatchStateLocked();
4331 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004332 } // release lock
4333
4334 // Wake up poll loop since it may need to make new input dispatching choices.
4335 mLooper->wake();
4336}
4337
Michael Wrightd02c5b62014-02-10 15:10:22 -08004338void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004339 if (DEBUG_FOCUS) {
4340 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4341 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004342
4343 bool changed;
4344 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004345 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004346
4347 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4348 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004349 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004350 }
4351
4352 if (mDispatchEnabled && !enabled) {
4353 resetAndDropEverythingLocked("dispatcher is being disabled");
4354 }
4355
4356 mDispatchEnabled = enabled;
4357 mDispatchFrozen = frozen;
4358 changed = true;
4359 } else {
4360 changed = false;
4361 }
4362
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004363 if (DEBUG_FOCUS) {
4364 logDispatchStateLocked();
4365 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004366 } // release lock
4367
4368 if (changed) {
4369 // Wake up poll loop since it may need to make new input dispatching choices.
4370 mLooper->wake();
4371 }
4372}
4373
4374void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004375 if (DEBUG_FOCUS) {
4376 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4377 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004378
4379 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004380 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004381
4382 if (mInputFilterEnabled == enabled) {
4383 return;
4384 }
4385
4386 mInputFilterEnabled = enabled;
4387 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4388 } // release lock
4389
4390 // Wake up poll loop since there might be work to do to drop everything.
4391 mLooper->wake();
4392}
4393
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004394void InputDispatcher::setInTouchMode(bool inTouchMode) {
4395 std::scoped_lock lock(mLock);
4396 mInTouchMode = inTouchMode;
4397}
4398
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004399void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4400 if (opacity < 0 || opacity > 1) {
4401 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4402 return;
4403 }
4404
4405 std::scoped_lock lock(mLock);
4406 mMaximumObscuringOpacityForTouch = opacity;
4407}
4408
4409void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4410 std::scoped_lock lock(mLock);
4411 mBlockUntrustedTouchesMode = mode;
4412}
4413
chaviwfbe5d9c2018-12-26 12:23:37 -08004414bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4415 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004416 if (DEBUG_FOCUS) {
4417 ALOGD("Trivial transfer to same window.");
4418 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004419 return true;
4420 }
4421
Michael Wrightd02c5b62014-02-10 15:10:22 -08004422 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004423 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004424
chaviwfbe5d9c2018-12-26 12:23:37 -08004425 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4426 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004427 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004428 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004429 return false;
4430 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004431 if (DEBUG_FOCUS) {
4432 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4433 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4434 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004435 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004436 if (DEBUG_FOCUS) {
4437 ALOGD("Cannot transfer focus because windows are on different displays.");
4438 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004439 return false;
4440 }
4441
4442 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004443 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4444 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004445 for (size_t i = 0; i < state.windows.size(); i++) {
4446 const TouchedWindow& touchedWindow = state.windows[i];
4447 if (touchedWindow.windowHandle == fromWindowHandle) {
4448 int32_t oldTargetFlags = touchedWindow.targetFlags;
4449 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004450
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004451 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004452
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004453 int32_t newTargetFlags = oldTargetFlags &
4454 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4455 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004456 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004457
Jeff Brownf086ddb2014-02-11 14:28:48 -08004458 found = true;
4459 goto Found;
4460 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004461 }
4462 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004463 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004464
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004465 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004466 if (DEBUG_FOCUS) {
4467 ALOGD("Focus transfer failed because from window did not have focus.");
4468 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004469 return false;
4470 }
4471
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004472 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4473 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004474 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004475 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004476 CancelationOptions
4477 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4478 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004479 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004480 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004481 }
4482
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004483 if (DEBUG_FOCUS) {
4484 logDispatchStateLocked();
4485 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004486 } // release lock
4487
4488 // Wake up poll loop since it may need to make new input dispatching choices.
4489 mLooper->wake();
4490 return true;
4491}
4492
4493void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004494 if (DEBUG_FOCUS) {
4495 ALOGD("Resetting and dropping all events (%s).", reason);
4496 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004497
4498 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4499 synthesizeCancelationEventsForAllConnectionsLocked(options);
4500
4501 resetKeyRepeatLocked();
4502 releasePendingEventLocked();
4503 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004504 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004505
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004506 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004507 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004508 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004509 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004510}
4511
4512void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004513 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004514 dumpDispatchStateLocked(dump);
4515
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004516 std::istringstream stream(dump);
4517 std::string line;
4518
4519 while (std::getline(stream, line, '\n')) {
4520 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004521 }
4522}
4523
Vishnu Nairad321cd2020-08-20 16:40:21 -07004524std::string InputDispatcher::dumpFocusedWindowsLocked() {
4525 if (mFocusedWindowTokenByDisplay.empty()) {
4526 return INDENT "FocusedWindows: <none>\n";
4527 }
4528
4529 std::string dump;
4530 dump += INDENT "FocusedWindows:\n";
4531 for (auto& it : mFocusedWindowTokenByDisplay) {
4532 const int32_t displayId = it.first;
4533 const sp<InputWindowHandle> windowHandle = getFocusedWindowHandleLocked(displayId);
4534 if (windowHandle) {
4535 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
4536 windowHandle->getName().c_str());
4537 } else {
4538 dump += StringPrintf(INDENT2 "displayId=%" PRId32
4539 " has focused token without a window'\n",
4540 displayId);
4541 }
4542 }
4543 return dump;
4544}
4545
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004546std::string InputDispatcher::dumpPendingFocusRequestsLocked() {
4547 if (mPendingFocusRequests.empty()) {
4548 return INDENT "mPendingFocusRequests: <none>\n";
4549 }
4550
4551 std::string dump;
4552 dump += INDENT "mPendingFocusRequests:\n";
4553 for (const auto& [displayId, focusRequest] : mPendingFocusRequests) {
4554 // Rather than printing raw values for focusRequest.token and focusRequest.focusedToken,
4555 // try to resolve them to actual windows.
4556 std::string windowName = getConnectionNameLocked(focusRequest.token);
4557 std::string focusedWindowName = getConnectionNameLocked(focusRequest.focusedToken);
4558 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", token->%s, focusedToken->%s\n",
4559 displayId, windowName.c_str(), focusedWindowName.c_str());
4560 }
4561 return dump;
4562}
4563
Prabir Pradhan99987712020-11-10 18:43:05 -08004564std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4565 std::string dump;
4566
4567 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4568 toString(mFocusedWindowRequestedPointerCapture));
4569
4570 std::string windowName = "None";
4571 if (mWindowTokenWithPointerCapture) {
4572 const sp<InputWindowHandle> captureWindowHandle =
4573 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4574 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4575 : "token has capture without window";
4576 }
4577 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4578
4579 return dump;
4580}
4581
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004582void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004583 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4584 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4585 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004586 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004587
Tiger Huang721e26f2018-07-24 22:26:19 +08004588 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4589 dump += StringPrintf(INDENT "FocusedApplications:\n");
4590 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4591 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004592 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004593 const std::chrono::duration timeout =
4594 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004595 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004596 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004597 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004598 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004599 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004600 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004601 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004602
Vishnu Nairad321cd2020-08-20 16:40:21 -07004603 dump += dumpFocusedWindowsLocked();
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004604 dump += dumpPendingFocusRequestsLocked();
Prabir Pradhan99987712020-11-10 18:43:05 -08004605 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004606
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004607 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004608 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004609 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4610 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004611 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004612 state.displayId, toString(state.down), toString(state.split),
4613 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004614 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004615 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004616 for (size_t i = 0; i < state.windows.size(); i++) {
4617 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004618 dump += StringPrintf(INDENT4
4619 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4620 i, touchedWindow.windowHandle->getName().c_str(),
4621 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004622 }
4623 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004624 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004625 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004626 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004627 dump += INDENT3 "Portal windows:\n";
4628 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004629 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004630 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4631 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004632 }
4633 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004634 }
4635 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004636 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004637 }
4638
Arthur Hungb92218b2018-08-14 12:00:21 +08004639 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004640 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004641 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004642 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004643 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004644 dump += INDENT2 "Windows:\n";
4645 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004646 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004647 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004648
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004649 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004650 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004651 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004652 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004653 "frame=[%d,%d][%d,%d], globalScale=%f, "
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004654 "applicationInfo=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004655 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004656 i, windowInfo->name.c_str(), windowInfo->id,
4657 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004658 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004659 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004660 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004661 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004662 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004663 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004664 windowInfo->frameLeft, windowInfo->frameTop,
4665 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004666 windowInfo->globalScaleFactor,
4667 windowInfo->applicationInfo.name.c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004668 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004669 dump += StringPrintf(", inputFeatures=%s",
4670 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004671 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004672 "ms, trustedOverlay=%s, hasToken=%s, "
4673 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004674 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004675 millis(windowInfo->dispatchingTimeout),
4676 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004677 toString(windowInfo->token != nullptr),
4678 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004679 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004680 }
4681 } else {
4682 dump += INDENT2 "Windows: <none>\n";
4683 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004684 }
4685 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004686 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004687 }
4688
Michael Wright3dd60e22019-03-27 22:06:44 +00004689 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004690 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004691 const std::vector<Monitor>& monitors = it.second;
4692 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4693 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004694 }
4695 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004696 const std::vector<Monitor>& monitors = it.second;
4697 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4698 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004699 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004700 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004701 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004702 }
4703
4704 nsecs_t currentTime = now();
4705
4706 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004707 if (!mRecentQueue.empty()) {
4708 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004709 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004710 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004711 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004712 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004713 }
4714 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004715 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004716 }
4717
4718 // Dump event currently being dispatched.
4719 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004720 dump += INDENT "PendingEvent:\n";
4721 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004722 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004723 dump += StringPrintf(", age=%" PRId64 "ms\n",
4724 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004725 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004726 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004727 }
4728
4729 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004730 if (!mInboundQueue.empty()) {
4731 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004732 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004733 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004734 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004735 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004736 }
4737 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004738 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004739 }
4740
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004741 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004742 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004743 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4744 const KeyReplacement& replacement = pair.first;
4745 int32_t newKeyCode = pair.second;
4746 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004747 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004748 }
4749 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004750 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004751 }
4752
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004753 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004754 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004755 for (const auto& pair : mConnectionsByFd) {
4756 const sp<Connection>& connection = pair.second;
4757 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004758 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004759 pair.first, connection->getInputChannelName().c_str(),
4760 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004761 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004762
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004763 if (!connection->outboundQueue.empty()) {
4764 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4765 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004766 dump += dumpQueue(connection->outboundQueue, currentTime);
4767
Michael Wrightd02c5b62014-02-10 15:10:22 -08004768 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004769 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004770 }
4771
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004772 if (!connection->waitQueue.empty()) {
4773 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4774 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004775 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004776 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004777 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004778 }
4779 }
4780 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004781 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004782 }
4783
4784 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004785 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4786 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004787 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004788 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004789 }
4790
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004791 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004792 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4793 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4794 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004795}
4796
Michael Wright3dd60e22019-03-27 22:06:44 +00004797void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4798 const size_t numMonitors = monitors.size();
4799 for (size_t i = 0; i < numMonitors; i++) {
4800 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004801 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004802 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4803 dump += "\n";
4804 }
4805}
4806
Garfield Tan15601662020-09-22 15:32:38 -07004807base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4808 const std::string& name) {
4809#if DEBUG_CHANNEL_CREATION
4810 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004811#endif
4812
Garfield Tan15601662020-09-22 15:32:38 -07004813 std::shared_ptr<InputChannel> serverChannel;
4814 std::unique_ptr<InputChannel> clientChannel;
4815 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4816
4817 if (result) {
4818 return base::Error(result) << "Failed to open input channel pair with name " << name;
4819 }
4820
Michael Wrightd02c5b62014-02-10 15:10:22 -08004821 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004822 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004823 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004824
Garfield Tan15601662020-09-22 15:32:38 -07004825 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004826 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004827 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004828
Michael Wrightd02c5b62014-02-10 15:10:22 -08004829 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4830 } // release lock
4831
4832 // Wake the looper because some connections have changed.
4833 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004834 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004835}
4836
Garfield Tan15601662020-09-22 15:32:38 -07004837base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004838 int32_t displayId, bool isGestureMonitor, const std::string& name, int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07004839 std::shared_ptr<InputChannel> serverChannel;
4840 std::unique_ptr<InputChannel> clientChannel;
4841 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4842 if (result) {
4843 return base::Error(result) << "Failed to open input channel pair with name " << name;
4844 }
4845
Michael Wright3dd60e22019-03-27 22:06:44 +00004846 { // acquire lock
4847 std::scoped_lock _l(mLock);
4848
4849 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004850 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4851 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004852 }
4853
Garfield Tan15601662020-09-22 15:32:38 -07004854 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004855
Garfield Tan15601662020-09-22 15:32:38 -07004856 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004857 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004858 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004859
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004860 auto& monitorsByDisplay =
4861 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004862 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00004863
4864 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004865 }
Garfield Tan15601662020-09-22 15:32:38 -07004866
Michael Wright3dd60e22019-03-27 22:06:44 +00004867 // Wake the looper because some connections have changed.
4868 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004869 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004870}
4871
Garfield Tan15601662020-09-22 15:32:38 -07004872status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004873 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004874 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004875
Garfield Tan15601662020-09-22 15:32:38 -07004876 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004877 if (status) {
4878 return status;
4879 }
4880 } // release lock
4881
4882 // Wake the poll loop because removing the connection may have changed the current
4883 // synchronization state.
4884 mLooper->wake();
4885 return OK;
4886}
4887
Garfield Tan15601662020-09-22 15:32:38 -07004888status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
4889 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004890 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004891 if (connection == nullptr) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004892 ALOGW("Attempted to unregister already unregistered input channel");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004893 return BAD_VALUE;
4894 }
4895
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004896 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004897 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07004898
Michael Wrightd02c5b62014-02-10 15:10:22 -08004899 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004900 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004901 }
4902
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004903 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004904
4905 nsecs_t currentTime = now();
4906 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4907
4908 connection->status = Connection::STATUS_ZOMBIE;
4909 return OK;
4910}
4911
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004912void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
4913 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
4914 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00004915}
4916
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004917void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004918 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00004919 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004920 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004921 std::vector<Monitor>& monitors = it->second;
4922 const size_t numMonitors = monitors.size();
4923 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004924 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004925 monitors.erase(monitors.begin() + i);
4926 break;
4927 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004928 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004929 if (monitors.empty()) {
4930 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004931 } else {
4932 ++it;
4933 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004934 }
4935}
4936
Michael Wright3dd60e22019-03-27 22:06:44 +00004937status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4938 { // acquire lock
4939 std::scoped_lock _l(mLock);
4940 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4941
4942 if (!foundDisplayId) {
4943 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4944 return BAD_VALUE;
4945 }
4946 int32_t displayId = foundDisplayId.value();
4947
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004948 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4949 mTouchStatesByDisplay.find(displayId);
4950 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004951 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4952 return BAD_VALUE;
4953 }
4954
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004955 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00004956 std::optional<int32_t> foundDeviceId;
4957 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07004958 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004959 foundDeviceId = state.deviceId;
4960 }
4961 }
4962 if (!foundDeviceId || !state.down) {
4963 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004964 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004965 return BAD_VALUE;
4966 }
4967 int32_t deviceId = foundDeviceId.value();
4968
4969 // Send cancel events to all the input channels we're stealing from.
4970 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004971 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004972 options.deviceId = deviceId;
4973 options.displayId = displayId;
4974 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004975 std::shared_ptr<InputChannel> channel =
4976 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00004977 if (channel != nullptr) {
4978 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4979 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004980 }
4981 // Then clear the current touch state so we stop dispatching to them as well.
4982 state.filterNonMonitors();
4983 }
4984 return OK;
4985}
4986
Prabir Pradhan99987712020-11-10 18:43:05 -08004987void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
4988 { // acquire lock
4989 std::scoped_lock _l(mLock);
4990 if (DEBUG_FOCUS) {
4991 const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
4992 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
4993 windowHandle != nullptr ? windowHandle->getName().c_str()
4994 : "token without window");
4995 }
4996
4997 const sp<IBinder> focusedToken =
4998 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4999 if (focusedToken != windowToken) {
5000 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5001 enabled ? "enable" : "disable");
5002 return;
5003 }
5004
5005 if (enabled == mFocusedWindowRequestedPointerCapture) {
5006 ALOGW("Ignoring request to %s Pointer Capture: "
5007 "window has %s requested pointer capture.",
5008 enabled ? "enable" : "disable", enabled ? "already" : "not");
5009 return;
5010 }
5011
5012 mFocusedWindowRequestedPointerCapture = enabled;
5013 setPointerCaptureLocked(enabled);
5014 } // release lock
5015
5016 // Wake the thread to process command entries.
5017 mLooper->wake();
5018}
5019
Michael Wright3dd60e22019-03-27 22:06:44 +00005020std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5021 const sp<IBinder>& token) {
5022 for (const auto& it : mGestureMonitorsByDisplay) {
5023 const std::vector<Monitor>& monitors = it.second;
5024 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005025 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005026 return it.first;
5027 }
5028 }
5029 }
5030 return std::nullopt;
5031}
5032
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005033sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005034 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005035 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005036 }
5037
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005038 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005039 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005040 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005041 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005042 }
5043 }
Robert Carr4e670e52018-08-15 13:26:12 -07005044
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005045 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005046}
5047
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005048std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5049 sp<Connection> connection = getConnectionLocked(connectionToken);
5050 if (connection == nullptr) {
5051 return "<nullptr>";
5052 }
5053 return connection->getInputChannelName();
5054}
5055
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005056void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005057 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005058 removeByValue(mConnectionsByFd, connection);
5059}
5060
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005061void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5062 const sp<Connection>& connection, uint32_t seq,
5063 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005064 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5065 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005066 commandEntry->connection = connection;
5067 commandEntry->eventTime = currentTime;
5068 commandEntry->seq = seq;
5069 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005070 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005071}
5072
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005073void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5074 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005075 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005076 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005077
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005078 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5079 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005080 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005081 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005082}
5083
Vishnu Nairad321cd2020-08-20 16:40:21 -07005084void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5085 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005086 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5087 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005088 commandEntry->oldToken = oldToken;
5089 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005090 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005091}
5092
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005093void InputDispatcher::onAnrLocked(const Connection& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005094 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5095 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005096 if (connection.waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005097 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005098 connection.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005099 return;
5100 }
5101 /**
5102 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5103 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5104 * has changed. This could cause newer entries to time out before the already dispatched
5105 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5106 * processes the events linearly. So providing information about the oldest entry seems to be
5107 * most useful.
5108 */
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005109 DispatchEntry* oldestEntry = *connection.waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005110 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5111 std::string reason =
5112 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005113 connection.inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005114 ns2ms(currentWait),
5115 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005116 sp<IBinder> connectionToken = connection.inputChannel->getConnectionToken();
5117 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005118
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005119 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5120 &InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible);
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005121 commandEntry->connectionToken = connectionToken;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005122 commandEntry->reason = std::move(reason);
5123 postCommandLocked(std::move(commandEntry));
5124}
5125
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005126void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5127 std::string reason =
5128 StringPrintf("%s does not have a focused window", application->getName().c_str());
5129 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005130
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005131 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5132 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5133 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005134 postCommandLocked(std::move(commandEntry));
5135}
5136
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005137void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5138 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5139 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5140 commandEntry->obscuringPackage = obscuringPackage;
5141 postCommandLocked(std::move(commandEntry));
5142}
5143
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005144void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
5145 const std::string& reason) {
5146 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5147 updateLastAnrStateLocked(windowLabel, reason);
5148}
5149
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005150void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5151 const std::string& reason) {
5152 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005153 updateLastAnrStateLocked(windowLabel, reason);
5154}
5155
5156void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5157 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005158 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005159 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005160 struct tm tm;
5161 localtime_r(&t, &tm);
5162 char timestr[64];
5163 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005164 mLastAnrState.clear();
5165 mLastAnrState += INDENT "ANR:\n";
5166 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005167 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5168 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005169 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005170}
5171
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005172void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005173 mLock.unlock();
5174
5175 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5176
5177 mLock.lock();
5178}
5179
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005180void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005181 sp<Connection> connection = commandEntry->connection;
5182
5183 if (connection->status != Connection::STATUS_ZOMBIE) {
5184 mLock.unlock();
5185
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005186 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005187
5188 mLock.lock();
5189 }
5190}
5191
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005192void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005193 sp<IBinder> oldToken = commandEntry->oldToken;
5194 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005195 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005196 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005197 mLock.lock();
5198}
5199
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005200void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005201 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005202
5203 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5204
5205 mLock.lock();
5206}
5207
5208void InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible(
5209 CommandEntry* commandEntry) {
5210 mLock.unlock();
5211
5212 mPolicy->notifyConnectionUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005213
5214 mLock.lock();
5215
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005216 // stop waking up for events in this connection, it is already not responding
5217 sp<Connection> connection = getConnectionLocked(commandEntry->connectionToken);
5218 if (connection == nullptr) {
5219 return;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005220 }
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005221 cancelEventsForAnrLocked(connection);
5222}
5223
5224void InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5225 mLock.unlock();
5226
5227 mPolicy->notifyConnectionResponsive(commandEntry->connectionToken);
5228
5229 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005230}
5231
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005232void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5233 mLock.unlock();
5234
5235 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5236
5237 mLock.lock();
5238}
5239
Michael Wrightd02c5b62014-02-10 15:10:22 -08005240void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5241 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005242 KeyEntry& entry = *(commandEntry->keyEntry);
5243 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005244
5245 mLock.unlock();
5246
Michael Wright2b3c3302018-03-02 17:19:13 +00005247 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005248 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005249 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005250 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5251 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005252 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005253 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005254
5255 mLock.lock();
5256
5257 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005258 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005259 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005260 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005261 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005262 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5263 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005264 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005265}
5266
chaviwfd6d3512019-03-25 13:23:49 -07005267void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5268 mLock.unlock();
5269 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5270 mLock.lock();
5271}
5272
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005273/**
5274 * Connection is responsive if it has no events in the waitQueue that are older than the
5275 * current time.
5276 */
5277static bool isConnectionResponsive(const Connection& connection) {
5278 const nsecs_t currentTime = now();
5279 for (const DispatchEntry* entry : connection.waitQueue) {
5280 if (entry->timeoutTime < currentTime) {
5281 return false;
5282 }
5283 }
5284 return true;
5285}
5286
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005287void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005288 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005289 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005290 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005291 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005292
5293 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005294 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005295 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005296 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005297 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005298 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005299 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005300 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005301 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5302 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005303 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005304 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005305
5306 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005307 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005308 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005309 restartEvent =
5310 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005311 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005312 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005313 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5314 handled);
5315 } else {
5316 restartEvent = false;
5317 }
5318
5319 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005320 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005321 // contents of the wait queue to have been drained, so we need to double-check
5322 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005323 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5324 if (dispatchEntryIt != connection->waitQueue.end()) {
5325 dispatchEntry = *dispatchEntryIt;
5326 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005327 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5328 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005329 if (!connection->responsive) {
5330 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005331 if (connection->responsive) {
5332 // The connection was unresponsive, and now it's responsive. Tell the policy
5333 // about it so that it can stop ANR.
5334 std::unique_ptr<CommandEntry> connectionResponsiveCommand =
5335 std::make_unique<CommandEntry>(
5336 &InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible);
5337 connectionResponsiveCommand->connectionToken = connectionToken;
5338 postCommandLocked(std::move(connectionResponsiveCommand));
5339 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005340 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005341 traceWaitQueueLength(connection);
5342 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005343 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005344 traceOutboundQueueLength(connection);
5345 } else {
5346 releaseDispatchEntry(dispatchEntry);
5347 }
5348 }
5349
5350 // Start the next dispatch cycle for this connection.
5351 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005352}
5353
5354bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005355 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005356 KeyEntry& keyEntry, bool handled) {
5357 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005358 if (!handled) {
5359 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005360 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005361 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005362 return false;
5363 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005364
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005365 // Get the fallback key state.
5366 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005367 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005368 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005369 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005370 connection->inputState.removeFallbackKey(originalKeyCode);
5371 }
5372
5373 if (handled || !dispatchEntry->hasForegroundTarget()) {
5374 // If the application handles the original key for which we previously
5375 // generated a fallback or if the window is not a foreground window,
5376 // then cancel the associated fallback key, if any.
5377 if (fallbackKeyCode != -1) {
5378 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005379#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005380 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005381 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005382 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005383#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005384 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005385 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005386
5387 mLock.unlock();
5388
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005389 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005390 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005391
5392 mLock.lock();
5393
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005394 // Cancel the fallback key.
5395 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005396 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005397 "application handled the original non-fallback key "
5398 "or is no longer a foreground target, "
5399 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005400 options.keyCode = fallbackKeyCode;
5401 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005402 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005403 connection->inputState.removeFallbackKey(originalKeyCode);
5404 }
5405 } else {
5406 // If the application did not handle a non-fallback key, first check
5407 // that we are in a good state to perform unhandled key event processing
5408 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005409 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005410 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005411#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005412 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005413 "since this is not an initial down. "
5414 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005415 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005416#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005417 return false;
5418 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005419
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005420 // Dispatch the unhandled key to the policy.
5421#if DEBUG_OUTBOUND_EVENT_DETAILS
5422 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005423 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005424 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005425#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005426 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005427
5428 mLock.unlock();
5429
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005430 bool fallback =
5431 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005432 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005433
5434 mLock.lock();
5435
5436 if (connection->status != Connection::STATUS_NORMAL) {
5437 connection->inputState.removeFallbackKey(originalKeyCode);
5438 return false;
5439 }
5440
5441 // Latch the fallback keycode for this key on an initial down.
5442 // The fallback keycode cannot change at any other point in the lifecycle.
5443 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005444 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005445 fallbackKeyCode = event.getKeyCode();
5446 } else {
5447 fallbackKeyCode = AKEYCODE_UNKNOWN;
5448 }
5449 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5450 }
5451
5452 ALOG_ASSERT(fallbackKeyCode != -1);
5453
5454 // Cancel the fallback key if the policy decides not to send it anymore.
5455 // We will continue to dispatch the key to the policy but we will no
5456 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005457 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5458 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005459#if DEBUG_OUTBOUND_EVENT_DETAILS
5460 if (fallback) {
5461 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005462 "as a fallback for %d, but on the DOWN it had requested "
5463 "to send %d instead. Fallback canceled.",
5464 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005465 } else {
5466 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005467 "but on the DOWN it had requested to send %d. "
5468 "Fallback canceled.",
5469 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005470 }
5471#endif
5472
5473 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5474 "canceling fallback, policy no longer desires it");
5475 options.keyCode = fallbackKeyCode;
5476 synthesizeCancelationEventsForConnectionLocked(connection, options);
5477
5478 fallback = false;
5479 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005480 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005481 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005482 }
5483 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005484
5485#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005486 {
5487 std::string msg;
5488 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5489 connection->inputState.getFallbackKeys();
5490 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005491 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005492 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005493 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005494 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005495 }
5496#endif
5497
5498 if (fallback) {
5499 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005500 keyEntry.eventTime = event.getEventTime();
5501 keyEntry.deviceId = event.getDeviceId();
5502 keyEntry.source = event.getSource();
5503 keyEntry.displayId = event.getDisplayId();
5504 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5505 keyEntry.keyCode = fallbackKeyCode;
5506 keyEntry.scanCode = event.getScanCode();
5507 keyEntry.metaState = event.getMetaState();
5508 keyEntry.repeatCount = event.getRepeatCount();
5509 keyEntry.downTime = event.getDownTime();
5510 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005511
5512#if DEBUG_OUTBOUND_EVENT_DETAILS
5513 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005514 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005515 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005516#endif
5517 return true; // restart the event
5518 } else {
5519#if DEBUG_OUTBOUND_EVENT_DETAILS
5520 ALOGD("Unhandled key event: No fallback key.");
5521#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005522
5523 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005524 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005525 }
5526 }
5527 return false;
5528}
5529
5530bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005531 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005532 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005533 return false;
5534}
5535
5536void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5537 mLock.unlock();
5538
5539 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5540
5541 mLock.lock();
5542}
5543
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005544void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5545 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005546 // TODO Write some statistics about how long we spend waiting.
5547}
5548
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005549/**
5550 * Report the touch event latency to the statsd server.
5551 * Input events are reported for statistics if:
5552 * - This is a touchscreen event
5553 * - InputFilter is not enabled
5554 * - Event is not injected or synthesized
5555 *
5556 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5557 * from getting aggregated with the "old" data.
5558 */
5559void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5560 REQUIRES(mLock) {
5561 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5562 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5563 if (!reportForStatistics) {
5564 return;
5565 }
5566
5567 if (mTouchStatistics.shouldReport()) {
5568 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5569 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5570 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5571 mTouchStatistics.reset();
5572 }
5573 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5574 mTouchStatistics.addValue(latencyMicros);
5575}
5576
Michael Wrightd02c5b62014-02-10 15:10:22 -08005577void InputDispatcher::traceInboundQueueLengthLocked() {
5578 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005579 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005580 }
5581}
5582
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005583void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005584 if (ATRACE_ENABLED()) {
5585 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005586 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005587 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005588 }
5589}
5590
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005591void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005592 if (ATRACE_ENABLED()) {
5593 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005594 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005595 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005596 }
5597}
5598
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005599void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005600 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005601
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005602 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005603 dumpDispatchStateLocked(dump);
5604
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005605 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005606 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005607 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005608 }
5609}
5610
5611void InputDispatcher::monitor() {
5612 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005613 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005614 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005615 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005616}
5617
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005618/**
5619 * Wake up the dispatcher and wait until it processes all events and commands.
5620 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5621 * this method can be safely called from any thread, as long as you've ensured that
5622 * the work you are interested in completing has already been queued.
5623 */
5624bool InputDispatcher::waitForIdle() {
5625 /**
5626 * Timeout should represent the longest possible time that a device might spend processing
5627 * events and commands.
5628 */
5629 constexpr std::chrono::duration TIMEOUT = 100ms;
5630 std::unique_lock lock(mLock);
5631 mLooper->wake();
5632 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5633 return result == std::cv_status::no_timeout;
5634}
5635
Vishnu Naire798b472020-07-23 13:52:21 -07005636/**
5637 * Sets focus to the window identified by the token. This must be called
5638 * after updating any input window handles.
5639 *
5640 * Params:
5641 * request.token - input channel token used to identify the window that should gain focus.
5642 * request.focusedToken - the token that the caller expects currently to be focused. If the
5643 * specified token does not match the currently focused window, this request will be dropped.
5644 * If the specified focused token matches the currently focused window, the call will succeed.
5645 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5646 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5647 * when requesting the focus change. This determines which request gets
5648 * precedence if there is a focus change request from another source such as pointer down.
5649 */
Vishnu Nair958da932020-08-21 17:12:37 -07005650void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5651 { // acquire lock
5652 std::scoped_lock _l(mLock);
5653
5654 const int32_t displayId = request.displayId;
5655 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5656 if (request.focusedToken && oldFocusedToken != request.focusedToken) {
5657 ALOGD_IF(DEBUG_FOCUS,
5658 "setFocusedWindow on display %" PRId32
5659 " ignored, reason: focusedToken is not focused",
5660 displayId);
5661 return;
5662 }
5663
5664 mPendingFocusRequests.erase(displayId);
5665 FocusResult result = handleFocusRequestLocked(request);
5666 if (result == FocusResult::NOT_VISIBLE) {
5667 // The requested window is not currently visible. Wait for the window to become visible
5668 // and then provide it focus. This is to handle situations where a user action triggers
5669 // a new window to appear. We want to be able to queue any key events after the user
5670 // action and deliver it to the newly focused window. In order for this to happen, we
5671 // take focus from the currently focused window so key events can be queued.
5672 ALOGD_IF(DEBUG_FOCUS,
5673 "setFocusedWindow on display %" PRId32
5674 " pending, reason: window is not visible",
5675 displayId);
5676 mPendingFocusRequests[displayId] = request;
5677 onFocusChangedLocked(oldFocusedToken, nullptr, displayId,
5678 "setFocusedWindow_AwaitingWindowVisibility");
5679 } else if (result != FocusResult::OK) {
5680 ALOGW("setFocusedWindow on display %" PRId32 " ignored, reason:%s", displayId,
5681 typeToString(result));
5682 }
5683 } // release lock
5684 // Wake up poll loop since it may need to make new input dispatching choices.
5685 mLooper->wake();
5686}
5687
5688InputDispatcher::FocusResult InputDispatcher::handleFocusRequestLocked(
5689 const FocusRequest& request) {
5690 const int32_t displayId = request.displayId;
5691 const sp<IBinder> newFocusedToken = request.token;
5692 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5693
5694 if (oldFocusedToken == request.token) {
5695 ALOGD_IF(DEBUG_FOCUS,
5696 "setFocusedWindow on display %" PRId32 " ignored, reason: already focused",
5697 displayId);
5698 return FocusResult::OK;
5699 }
5700
5701 FocusResult result = checkTokenFocusableLocked(newFocusedToken, displayId);
5702 if (result != FocusResult::OK) {
5703 return result;
5704 }
5705
5706 std::string_view reason =
5707 (request.focusedToken) ? "setFocusedWindow_FocusCheck" : "setFocusedWindow";
5708 onFocusChangedLocked(oldFocusedToken, newFocusedToken, displayId, reason);
5709 return FocusResult::OK;
5710}
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005711
Vishnu Nairad321cd2020-08-20 16:40:21 -07005712void InputDispatcher::onFocusChangedLocked(const sp<IBinder>& oldFocusedToken,
5713 const sp<IBinder>& newFocusedToken, int32_t displayId,
5714 std::string_view reason) {
5715 if (oldFocusedToken) {
5716 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(oldFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005717 if (focusedInputChannel) {
5718 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5719 "focus left window");
5720 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005721 enqueueFocusEventLocked(oldFocusedToken, false /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005722 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005723 mFocusedWindowTokenByDisplay.erase(displayId);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005724 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005725 if (newFocusedToken) {
5726 mFocusedWindowTokenByDisplay[displayId] = newFocusedToken;
5727 enqueueFocusEventLocked(newFocusedToken, true /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005728 }
5729
Prabir Pradhan99987712020-11-10 18:43:05 -08005730 // If a window has pointer capture, then it must have focus. We need to ensure that this
5731 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
5732 // If the window loses focus before it loses pointer capture, then the window can be in a state
5733 // where it has pointer capture but not focus, violating the contract. Therefore we must
5734 // dispatch the pointer capture event before the focus event. Since focus events are added to
5735 // the front of the queue (above), we add the pointer capture event to the front of the queue
5736 // after the focus events are added. This ensures the pointer capture event ends up at the
5737 // front.
5738 disablePointerCaptureForcedLocked();
5739
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005740 if (mFocusedDisplayId == displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005741 notifyFocusChangedLocked(oldFocusedToken, newFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005742 }
5743}
Vishnu Nair958da932020-08-21 17:12:37 -07005744
Prabir Pradhan99987712020-11-10 18:43:05 -08005745void InputDispatcher::disablePointerCaptureForcedLocked() {
5746 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
5747 return;
5748 }
5749
5750 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
5751
5752 if (mFocusedWindowRequestedPointerCapture) {
5753 mFocusedWindowRequestedPointerCapture = false;
5754 setPointerCaptureLocked(false);
5755 }
5756
5757 if (!mWindowTokenWithPointerCapture) {
5758 // No need to send capture changes because no window has capture.
5759 return;
5760 }
5761
5762 if (mPendingEvent != nullptr) {
5763 // Move the pending event to the front of the queue. This will give the chance
5764 // for the pending event to be dropped if it is a captured event.
5765 mInboundQueue.push_front(mPendingEvent);
5766 mPendingEvent = nullptr;
5767 }
5768
5769 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
5770 false /* hasCapture */);
5771 mInboundQueue.push_front(std::move(entry));
5772}
5773
Vishnu Nair958da932020-08-21 17:12:37 -07005774/**
5775 * Checks if the window token can be focused on a display. The token can be focused if there is
5776 * at least one window handle that is visible with the same token and all window handles with the
5777 * same token are focusable.
5778 *
5779 * In the case of mirroring, two windows may share the same window token and their visibility
5780 * might be different. Example, the mirrored window can cover the window its mirroring. However,
5781 * we expect the focusability of the windows to match since its hard to reason why one window can
5782 * receive focus events and the other cannot when both are backed by the same input channel.
5783 */
5784InputDispatcher::FocusResult InputDispatcher::checkTokenFocusableLocked(const sp<IBinder>& token,
5785 int32_t displayId) const {
5786 bool allWindowsAreFocusable = true;
5787 bool visibleWindowFound = false;
5788 bool windowFound = false;
5789 for (const sp<InputWindowHandle>& window : getWindowHandlesLocked(displayId)) {
5790 if (window->getToken() != token) {
5791 continue;
5792 }
5793 windowFound = true;
5794 if (window->getInfo()->visible) {
5795 // Check if at least a single window is visible.
5796 visibleWindowFound = true;
5797 }
5798 if (!window->getInfo()->focusable) {
5799 // Check if all windows with the window token are focusable.
5800 allWindowsAreFocusable = false;
5801 break;
5802 }
5803 }
5804
5805 if (!windowFound) {
5806 return FocusResult::NO_WINDOW;
5807 }
5808 if (!allWindowsAreFocusable) {
5809 return FocusResult::NOT_FOCUSABLE;
5810 }
5811 if (!visibleWindowFound) {
5812 return FocusResult::NOT_VISIBLE;
5813 }
5814
5815 return FocusResult::OK;
5816}
Prabir Pradhan99987712020-11-10 18:43:05 -08005817
5818void InputDispatcher::setPointerCaptureLocked(bool enabled) {
5819 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5820 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
5821 commandEntry->enabled = enabled;
5822 postCommandLocked(std::move(commandEntry));
5823}
5824
5825void InputDispatcher::doSetPointerCaptureLockedInterruptible(
5826 android::inputdispatcher::CommandEntry* commandEntry) {
5827 mLock.unlock();
5828
5829 mPolicy->setPointerCapture(commandEntry->enabled);
5830
5831 mLock.lock();
5832}
5833
Garfield Tane84e6f92019-08-29 17:28:41 -07005834} // namespace android::inputdispatcher