blob: 58ecb6b9e0a494a459b4bf35a6c51ebe4647162e [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
Prabir Pradhand2c9e8e2021-05-24 15:00:12 -070050#include <InputFlingerProperties.sysprop.h>
Michael Wright2b3c3302018-03-02 17:19:13 +000051#include <android-base/chrono_utils.h>
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080052#include <android-base/properties.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>
chaviw15fab6f2021-06-07 14:15:52 -050058#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080059#include <input/InputDevice.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 <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070064#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080065
Michael Wright44753b12020-07-08 13:48:11 +010066#include <cerrno>
67#include <cinttypes>
68#include <climits>
69#include <cstddef>
70#include <ctime>
71#include <queue>
72#include <sstream>
73
74#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070075#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010076
Michael Wrightd02c5b62014-02-10 15:10:22 -080077#define INDENT " "
78#define INDENT2 " "
79#define INDENT3 " "
80#define INDENT4 " "
81
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080082using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000083using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080084using android::base::StringPrintf;
chaviw3277faf2021-05-19 16:45:23 -050085using android::gui::FocusRequest;
86using android::gui::TouchOcclusionMode;
87using android::gui::WindowInfo;
88using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080089using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100090using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080091using android::os::InputEventInjectionResult;
92using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100093using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080094
Garfield Tane84e6f92019-08-29 17:28:41 -070095namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080096
Prabir Pradhan93a0f912021-04-21 13:47:42 -070097// When per-window-input-rotation is enabled, InputFlinger works in the un-rotated display
98// coordinates and SurfaceFlinger includes the display rotation in the input window transforms.
99static bool isPerWindowInputRotationEnabled() {
100 static const bool PER_WINDOW_INPUT_ROTATION =
Vadim Tryshev7719c7d2021-08-27 17:28:43 +0000101 sysprop::InputFlingerProperties::per_window_input_rotation().value_or(false);
Prabir Pradhand2c9e8e2021-05-24 15:00:12 -0700102
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700103 return PER_WINDOW_INPUT_ROTATION;
104}
105
Michael Wrightd02c5b62014-02-10 15:10:22 -0800106// Default input dispatching timeout if there is no focused application or paused window
107// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -0800108const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
109 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
110 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800111
112// Amount of time to allow for all pending events to be processed when an app switch
113// key is on the way. This is used to preempt input dispatch and drop input events
114// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000115constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800116
117// Amount of time to allow for an event to be dispatched (measured since its eventTime)
118// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000119constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800120
Michael Wrightd02c5b62014-02-10 15:10:22 -0800121// 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 +0000122constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
123
124// Log a warning when an interception call takes longer than this to process.
125constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800126
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700127// Additional key latency in case a connection is still processing some motion events.
128// This will help with the case when a user touched a button that opens a new window,
129// and gives us the chance to dispatch the key to this new window.
130constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
131
Michael Wrightd02c5b62014-02-10 15:10:22 -0800132// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000133constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
134
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000135// Event log tags. See EventLogTags.logtags for reference
136constexpr int LOGTAG_INPUT_INTERACTION = 62000;
137constexpr int LOGTAG_INPUT_FOCUS = 62001;
138
Michael Wrightd02c5b62014-02-10 15:10:22 -0800139static inline nsecs_t now() {
140 return systemTime(SYSTEM_TIME_MONOTONIC);
141}
142
143static inline const char* toString(bool value) {
144 return value ? "true" : "false";
145}
146
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000147static inline const std::string toString(sp<IBinder> binder) {
148 if (binder == nullptr) {
149 return "<null>";
150 }
151 return StringPrintf("%p", binder.get());
152}
153
Michael Wrightd02c5b62014-02-10 15:10:22 -0800154static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700155 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
156 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800157}
158
159static bool isValidKeyAction(int32_t action) {
160 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700161 case AKEY_EVENT_ACTION_DOWN:
162 case AKEY_EVENT_ACTION_UP:
163 return true;
164 default:
165 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800166 }
167}
168
169static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700170 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800171 ALOGE("Key event has invalid action code 0x%x", action);
172 return false;
173 }
174 return true;
175}
176
Michael Wright7b159c92015-05-14 14:48:03 +0100177static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800178 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700179 case AMOTION_EVENT_ACTION_DOWN:
180 case AMOTION_EVENT_ACTION_UP:
181 case AMOTION_EVENT_ACTION_CANCEL:
182 case AMOTION_EVENT_ACTION_MOVE:
183 case AMOTION_EVENT_ACTION_OUTSIDE:
184 case AMOTION_EVENT_ACTION_HOVER_ENTER:
185 case AMOTION_EVENT_ACTION_HOVER_MOVE:
186 case AMOTION_EVENT_ACTION_HOVER_EXIT:
187 case AMOTION_EVENT_ACTION_SCROLL:
188 return true;
189 case AMOTION_EVENT_ACTION_POINTER_DOWN:
190 case AMOTION_EVENT_ACTION_POINTER_UP: {
191 int32_t index = getMotionEventActionPointerIndex(action);
192 return index >= 0 && index < pointerCount;
193 }
194 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
195 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
196 return actionButton != 0;
197 default:
198 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800199 }
200}
201
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500202static int64_t millis(std::chrono::nanoseconds t) {
203 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
204}
205
Michael Wright7b159c92015-05-14 14:48:03 +0100206static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700207 const PointerProperties* pointerProperties) {
208 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800209 ALOGE("Motion event has invalid action code 0x%x", action);
210 return false;
211 }
212 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000213 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700214 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800215 return false;
216 }
217 BitSet32 pointerIdBits;
218 for (size_t i = 0; i < pointerCount; i++) {
219 int32_t id = pointerProperties[i].id;
220 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700221 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
222 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800223 return false;
224 }
225 if (pointerIdBits.hasBit(id)) {
226 ALOGE("Motion event has duplicate pointer id %d", id);
227 return false;
228 }
229 pointerIdBits.markBit(id);
230 }
231 return true;
232}
233
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000234static std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800235 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000236 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800237 }
238
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000239 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800240 bool first = true;
241 Region::const_iterator cur = region.begin();
242 Region::const_iterator const tail = region.end();
243 while (cur != tail) {
244 if (first) {
245 first = false;
246 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800247 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800248 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800249 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800250 cur++;
251 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000252 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800253}
254
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500255static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
256 constexpr size_t maxEntries = 50; // max events to print
257 constexpr size_t skipBegin = maxEntries / 2;
258 const size_t skipEnd = queue.size() - maxEntries / 2;
259 // skip from maxEntries / 2 ... size() - maxEntries/2
260 // only print from 0 .. skipBegin and then from skipEnd .. size()
261
262 std::string dump;
263 for (size_t i = 0; i < queue.size(); i++) {
264 const DispatchEntry& entry = *queue[i];
265 if (i >= skipBegin && i < skipEnd) {
266 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
267 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
268 continue;
269 }
270 dump.append(INDENT4);
271 dump += entry.eventEntry->getDescription();
272 dump += StringPrintf(", seq=%" PRIu32
273 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
274 entry.seq, entry.targetFlags, entry.resolvedAction,
275 ns2ms(currentTime - entry.eventEntry->eventTime));
276 if (entry.deliveryTime != 0) {
277 // This entry was delivered, so add information on how long we've been waiting
278 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
279 }
280 dump.append("\n");
281 }
282 return dump;
283}
284
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700285/**
286 * Find the entry in std::unordered_map by key, and return it.
287 * If the entry is not found, return a default constructed entry.
288 *
289 * Useful when the entries are vectors, since an empty vector will be returned
290 * if the entry is not found.
291 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
292 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700293template <typename K, typename V>
294static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700295 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700296 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800297}
298
chaviw3277faf2021-05-19 16:45:23 -0500299static bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700300 if (first == second) {
301 return true;
302 }
303
304 if (first == nullptr || second == nullptr) {
305 return false;
306 }
307
308 return first->getToken() == second->getToken();
309}
310
chaviw3277faf2021-05-19 16:45:23 -0500311static bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000312 if (first == nullptr || second == nullptr) {
313 return false;
314 }
315 return first->applicationInfo.token != nullptr &&
316 first->applicationInfo.token == second->applicationInfo.token;
317}
318
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800319static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
320 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
321}
322
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000323static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700324 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000325 int32_t inputTargetFlags) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900326 if (eventEntry->type == EventEntry::Type::MOTION) {
327 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
Prabir Pradhan664834b2021-05-20 16:00:42 -0700328 if ((motionEntry.source & AINPUT_SOURCE_CLASS_JOYSTICK) ||
329 (motionEntry.source & AINPUT_SOURCE_CLASS_POSITION)) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900330 const ui::Transform identityTransform;
Prabir Pradhan664834b2021-05-20 16:00:42 -0700331 // Use identity transform for joystick and position-based (touchpad) events because they
332 // don't depend on the window transform.
yunho.shinf4a80b82020-11-16 21:13:57 +0900333 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700334 1.0f /*globalScaleFactor*/,
Evan Rosky09576692021-07-01 12:22:09 -0700335 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700336 inputTarget.displaySize);
yunho.shinf4a80b82020-11-16 21:13:57 +0900337 }
338 }
339
chaviw1ff3d1e2020-07-01 15:53:47 -0700340 if (inputTarget.useDefaultPointerTransform()) {
341 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700342 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700343 inputTarget.globalScaleFactor,
Evan Rosky09576692021-07-01 12:22:09 -0700344 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700345 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000346 }
347
348 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
349 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
350
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700351 std::vector<PointerCoords> pointerCoords;
352 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000353
354 // Use the first pointer information to normalize all other pointers. This could be any pointer
355 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700356 // uses the transform for the normalized pointer.
357 const ui::Transform& firstPointerTransform =
358 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
359 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000360
361 // Iterate through all pointers in the event to normalize against the first.
362 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
363 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
364 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700365 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000366
367 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700368 // First, apply the current pointer's transform to update the coordinates into
369 // window space.
370 pointerCoords[pointerIndex].transform(currTransform);
371 // Next, apply the inverse transform of the normalized coordinates so the
372 // current coordinates are transformed into the normalized coordinate space.
373 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000374 }
375
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700376 std::unique_ptr<MotionEntry> combinedMotionEntry =
377 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
378 motionEntry.deviceId, motionEntry.source,
379 motionEntry.displayId, motionEntry.policyFlags,
380 motionEntry.action, motionEntry.actionButton,
381 motionEntry.flags, motionEntry.metaState,
382 motionEntry.buttonState, motionEntry.classification,
383 motionEntry.edgeFlags, motionEntry.xPrecision,
384 motionEntry.yPrecision, motionEntry.xCursorPosition,
385 motionEntry.yCursorPosition, motionEntry.downTime,
386 motionEntry.pointerCount, motionEntry.pointerProperties,
387 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000388
389 if (motionEntry.injectionState) {
390 combinedMotionEntry->injectionState = motionEntry.injectionState;
391 combinedMotionEntry->injectionState->refCount += 1;
392 }
393
394 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700395 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Evan Rosky84f07f02021-04-16 10:42:42 -0700396 firstPointerTransform, inputTarget.globalScaleFactor,
Evan Rosky09576692021-07-01 12:22:09 -0700397 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700398 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000399 return dispatchEntry;
400}
401
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700402static void addGestureMonitors(const std::vector<Monitor>& monitors,
403 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
404 float yOffset = 0) {
405 if (monitors.empty()) {
406 return;
407 }
408 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
409 for (const Monitor& monitor : monitors) {
410 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
411 }
412}
413
Garfield Tan15601662020-09-22 15:32:38 -0700414static status_t openInputChannelPair(const std::string& name,
415 std::shared_ptr<InputChannel>& serverChannel,
416 std::unique_ptr<InputChannel>& clientChannel) {
417 std::unique_ptr<InputChannel> uniqueServerChannel;
418 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
419
420 serverChannel = std::move(uniqueServerChannel);
421 return result;
422}
423
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500424template <typename T>
425static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
426 if (lhs == nullptr && rhs == nullptr) {
427 return true;
428 }
429 if (lhs == nullptr || rhs == nullptr) {
430 return false;
431 }
432 return *lhs == *rhs;
433}
434
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000435static sp<IPlatformCompatNative> getCompatService() {
436 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
437 if (service == nullptr) {
438 ALOGE("Failed to link to compat service");
439 return nullptr;
440 }
441 return interface_cast<IPlatformCompatNative>(service);
442}
443
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000444static KeyEvent createKeyEvent(const KeyEntry& entry) {
445 KeyEvent event;
446 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
447 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
448 entry.repeatCount, entry.downTime, entry.eventTime);
449 return event;
450}
451
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000452static std::optional<int32_t> findMonitorPidByToken(
453 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
454 const sp<IBinder>& token) {
455 for (const auto& it : monitorsByDisplay) {
456 const std::vector<Monitor>& monitors = it.second;
457 for (const Monitor& monitor : monitors) {
458 if (monitor.inputChannel->getConnectionToken() == token) {
459 return monitor.pid;
460 }
461 }
462 }
463 return std::nullopt;
464}
465
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000466static bool shouldReportMetricsForConnection(const Connection& connection) {
467 // Do not keep track of gesture monitors. They receive every event and would disproportionately
468 // affect the statistics.
469 if (connection.monitor) {
470 return false;
471 }
472 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
473 if (!connection.responsive) {
474 return false;
475 }
476 return true;
477}
478
479static bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry,
480 const Connection& connection) {
481 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
482 const int32_t& inputEventId = eventEntry.id;
483 if (inputEventId != dispatchEntry.resolvedEventId) {
484 // Event was transmuted
485 return false;
486 }
487 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
488 return false;
489 }
490 // Only track latency for events that originated from hardware
491 if (eventEntry.isSynthesized()) {
492 return false;
493 }
494 const EventEntry::Type& inputEventEntryType = eventEntry.type;
495 if (inputEventEntryType == EventEntry::Type::KEY) {
496 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
497 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
498 return false;
499 }
500 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
501 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
502 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
503 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
504 return false;
505 }
506 } else {
507 // Not a key or a motion
508 return false;
509 }
510 if (!shouldReportMetricsForConnection(connection)) {
511 return false;
512 }
513 return true;
514}
515
Michael Wrightd02c5b62014-02-10 15:10:22 -0800516// --- InputDispatcher ---
517
Garfield Tan00f511d2019-06-12 16:55:40 -0700518InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
519 : mPolicy(policy),
520 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700521 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800522 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700523 mAppSwitchSawKeyDown(false),
524 mAppSwitchDueTime(LONG_LONG_MAX),
525 mNextUnblockedEvent(nullptr),
526 mDispatchEnabled(false),
527 mDispatchFrozen(false),
528 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800529 // mInTouchMode will be initialized by the WindowManager to the default device config.
530 // To avoid leaking stack in case that call never comes, and for tests,
531 // initialize it here anyways.
532 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100533 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000534 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800535 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000536 mLatencyAggregator(),
537 mLatencyTracker(&mLatencyAggregator),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000538 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800539 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800540 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800541
Yi Kong9b14ac62018-07-17 13:48:38 -0700542 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800543
544 policy->getDispatcherConfiguration(&mConfig);
545}
546
547InputDispatcher::~InputDispatcher() {
548 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800549 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800550
551 resetKeyRepeatLocked();
552 releasePendingEventLocked();
553 drainInboundQueueLocked();
554 }
555
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000556 while (!mConnectionsByToken.empty()) {
557 sp<Connection> connection = mConnectionsByToken.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700558 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800559 }
560}
561
chaviw15fab6f2021-06-07 14:15:52 -0500562void InputDispatcher::onFirstRef() {
563 SurfaceComposerClient::getDefault()->addWindowInfosListener(this);
564}
565
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700566status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700567 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700568 return ALREADY_EXISTS;
569 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700570 mThread = std::make_unique<InputThread>(
571 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
572 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700573}
574
575status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700576 if (mThread && mThread->isCallingThread()) {
577 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700578 return INVALID_OPERATION;
579 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700580 mThread.reset();
581 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700582}
583
Michael Wrightd02c5b62014-02-10 15:10:22 -0800584void InputDispatcher::dispatchOnce() {
585 nsecs_t nextWakeupTime = LONG_LONG_MAX;
586 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800587 std::scoped_lock _l(mLock);
588 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800589
590 // Run a dispatch loop if there are no pending commands.
591 // The dispatch loop might enqueue commands to run afterwards.
592 if (!haveCommandsLocked()) {
593 dispatchOnceInnerLocked(&nextWakeupTime);
594 }
595
596 // Run all pending commands if there are any.
597 // If any commands were run then force the next poll to wake up immediately.
598 if (runCommandsLockedInterruptible()) {
599 nextWakeupTime = LONG_LONG_MIN;
600 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800601
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700602 // If we are still waiting for ack on some events,
603 // we might have to wake up earlier to check if an app is anr'ing.
604 const nsecs_t nextAnrCheck = processAnrsLocked();
605 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
606
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800607 // We are about to enter an infinitely long sleep, because we have no commands or
608 // pending or queued events
609 if (nextWakeupTime == LONG_LONG_MAX) {
610 mDispatcherEnteredIdle.notify_all();
611 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800612 } // release lock
613
614 // Wait for callback or timeout or wake. (make sure we round up, not down)
615 nsecs_t currentTime = now();
616 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
617 mLooper->pollOnce(timeoutMillis);
618}
619
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700620/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500621 * Raise ANR if there is no focused window.
622 * Before the ANR is raised, do a final state check:
623 * 1. The currently focused application must be the same one we are waiting for.
624 * 2. Ensure we still don't have a focused window.
625 */
626void InputDispatcher::processNoFocusedWindowAnrLocked() {
627 // Check if the application that we are waiting for is still focused.
628 std::shared_ptr<InputApplicationHandle> focusedApplication =
629 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
630 if (focusedApplication == nullptr ||
631 focusedApplication->getApplicationToken() !=
632 mAwaitedFocusedApplication->getApplicationToken()) {
633 // Unexpected because we should have reset the ANR timer when focused application changed
634 ALOGE("Waited for a focused window, but focused application has already changed to %s",
635 focusedApplication->getName().c_str());
636 return; // The focused application has changed.
637 }
638
chaviw3277faf2021-05-19 16:45:23 -0500639 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500640 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
641 if (focusedWindowHandle != nullptr) {
642 return; // We now have a focused window. No need for ANR.
643 }
644 onAnrLocked(mAwaitedFocusedApplication);
645}
646
647/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700648 * Check if any of the connections' wait queues have events that are too old.
649 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
650 * Return the time at which we should wake up next.
651 */
652nsecs_t InputDispatcher::processAnrsLocked() {
653 const nsecs_t currentTime = now();
654 nsecs_t nextAnrCheck = LONG_LONG_MAX;
655 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
656 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
657 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500658 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700659 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500660 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700661 return LONG_LONG_MIN;
662 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500663 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700664 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
665 }
666 }
667
668 // Check if any connection ANRs are due
669 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
670 if (currentTime < nextAnrCheck) { // most likely scenario
671 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
672 }
673
674 // If we reached here, we have an unresponsive connection.
675 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
676 if (connection == nullptr) {
677 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
678 return nextAnrCheck;
679 }
680 connection->responsive = false;
681 // Stop waking up for this unresponsive connection
682 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000683 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700684 return LONG_LONG_MIN;
685}
686
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500687std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
chaviw3277faf2021-05-19 16:45:23 -0500688 sp<WindowInfoHandle> window = getWindowHandleLocked(token);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700689 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500690 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700691 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500692 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700693}
694
Michael Wrightd02c5b62014-02-10 15:10:22 -0800695void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
696 nsecs_t currentTime = now();
697
Jeff Browndc5992e2014-04-11 01:27:26 -0700698 // Reset the key repeat timer whenever normal dispatch is suspended while the
699 // device is in a non-interactive state. This is to ensure that we abort a key
700 // repeat if the device is just coming out of sleep.
701 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800702 resetKeyRepeatLocked();
703 }
704
705 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
706 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100707 if (DEBUG_FOCUS) {
708 ALOGD("Dispatch frozen. Waiting some more.");
709 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800710 return;
711 }
712
713 // Optimize latency of app switches.
714 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
715 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
716 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
717 if (mAppSwitchDueTime < *nextWakeupTime) {
718 *nextWakeupTime = mAppSwitchDueTime;
719 }
720
721 // Ready to start a new event.
722 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700723 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700724 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800725 if (isAppSwitchDue) {
726 // The inbound queue is empty so the app switch key we were waiting
727 // for will never arrive. Stop waiting for it.
728 resetPendingAppSwitchLocked(false);
729 isAppSwitchDue = false;
730 }
731
732 // Synthesize a key repeat if appropriate.
733 if (mKeyRepeatState.lastKeyEntry) {
734 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
735 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
736 } else {
737 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
738 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
739 }
740 }
741 }
742
743 // Nothing to do if there is no pending event.
744 if (!mPendingEvent) {
745 return;
746 }
747 } else {
748 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700749 mPendingEvent = mInboundQueue.front();
750 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800751 traceInboundQueueLengthLocked();
752 }
753
754 // Poke user activity for this event.
755 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700756 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800757 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800758 }
759
760 // Now we have an event to dispatch.
761 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700762 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800763 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700764 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800765 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700766 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800767 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700768 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800769 }
770
771 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700772 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800773 }
774
775 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700776 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700777 const ConfigurationChangedEntry& typedEntry =
778 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700779 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700780 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700781 break;
782 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800783
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700784 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700785 const DeviceResetEntry& typedEntry =
786 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700787 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700788 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700789 break;
790 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800791
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100792 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700793 std::shared_ptr<FocusEntry> typedEntry =
794 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100795 dispatchFocusLocked(currentTime, typedEntry);
796 done = true;
797 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
798 break;
799 }
800
Prabir Pradhan99987712020-11-10 18:43:05 -0800801 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
802 const auto typedEntry =
803 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
804 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
805 done = true;
806 break;
807 }
808
arthurhungb89ccb02020-12-30 16:19:01 +0800809 case EventEntry::Type::DRAG: {
810 std::shared_ptr<DragEntry> typedEntry =
811 std::static_pointer_cast<DragEntry>(mPendingEvent);
812 dispatchDragLocked(currentTime, typedEntry);
813 done = true;
814 break;
815 }
816
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700817 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700818 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700819 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700820 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700821 resetPendingAppSwitchLocked(true);
822 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700823 } else if (dropReason == DropReason::NOT_DROPPED) {
824 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700825 }
826 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700827 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700828 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700829 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700830 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
831 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700832 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700833 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700834 break;
835 }
836
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700837 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700838 std::shared_ptr<MotionEntry> motionEntry =
839 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700840 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
841 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800842 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700843 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700844 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700845 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700846 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
847 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700848 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700849 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700850 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800851 }
Chris Yef59a2f42020-10-16 12:55:26 -0700852
853 case EventEntry::Type::SENSOR: {
854 std::shared_ptr<SensorEntry> sensorEntry =
855 std::static_pointer_cast<SensorEntry>(mPendingEvent);
856 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
857 dropReason = DropReason::APP_SWITCH;
858 }
859 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
860 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
861 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
862 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
863 dropReason = DropReason::STALE;
864 }
865 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
866 done = true;
867 break;
868 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800869 }
870
871 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700872 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700873 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800874 }
Michael Wright3a981722015-06-10 15:26:13 +0100875 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800876
877 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700878 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800879 }
880}
881
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700882/**
883 * Return true if the events preceding this incoming motion event should be dropped
884 * Return false otherwise (the default behaviour)
885 */
886bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700887 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700888 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700889
890 // Optimize case where the current application is unresponsive and the user
891 // decides to touch a window in a different application.
892 // If the application takes too long to catch up then we drop all events preceding
893 // the touch into the other window.
894 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700895 int32_t displayId = motionEntry.displayId;
896 int32_t x = static_cast<int32_t>(
897 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
898 int32_t y = static_cast<int32_t>(
899 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
chaviw3277faf2021-05-19 16:45:23 -0500900 sp<WindowInfoHandle> touchedWindowHandle =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700901 findTouchedWindowAtLocked(displayId, x, y, nullptr);
902 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700903 touchedWindowHandle->getApplicationToken() !=
904 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700905 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700906 ALOGI("Pruning input queue because user touched a different application while waiting "
907 "for %s",
908 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700909 return true;
910 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700911
912 // Alternatively, maybe there's a gesture monitor that could handle this event
913 std::vector<TouchedMonitor> gestureMonitors =
914 findTouchedGestureMonitorsLocked(displayId, {});
915 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
916 sp<Connection> connection =
917 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000918 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700919 // This monitor could take more input. Drop all events preceding this
920 // event, so that gesture monitor could get a chance to receive the stream
921 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
922 "responsive gesture monitor that may handle the event",
923 mAwaitedFocusedApplication->getName().c_str());
924 return true;
925 }
926 }
927 }
928
929 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
930 // yet been processed by some connections, the dispatcher will wait for these motion
931 // events to be processed before dispatching the key event. This is because these motion events
932 // may cause a new window to be launched, which the user might expect to receive focus.
933 // To prevent waiting forever for such events, just send the key to the currently focused window
934 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
935 ALOGD("Received a new pointer down event, stop waiting for events to process and "
936 "just send the pending key event to the focused window.");
937 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700938 }
939 return false;
940}
941
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700942bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700943 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700944 mInboundQueue.push_back(std::move(newEntry));
945 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800946 traceInboundQueueLengthLocked();
947
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700948 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700949 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700950 // Optimize app switch latency.
951 // If the application takes too long to catch up then we drop all events preceding
952 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700953 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700954 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700955 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700956 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700957 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700958 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800959#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700960 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800961#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700962 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700963 mAppSwitchSawKeyDown = false;
964 needWake = true;
965 }
966 }
967 }
968 break;
969 }
970
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700971 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700972 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
973 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700974 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800975 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700976 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800977 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100978 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700979 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
980 break;
981 }
982 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -0800983 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -0700984 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +0800985 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
986 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700987 // nothing to do
988 break;
989 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800990 }
991
992 return needWake;
993}
994
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700995void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -0700996 // Do not store sensor event in recent queue to avoid flooding the queue.
997 if (entry->type != EventEntry::Type::SENSOR) {
998 mRecentQueue.push_back(entry);
999 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001000 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001001 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001002 }
1003}
1004
chaviw3277faf2021-05-19 16:45:23 -05001005sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1006 int32_t y, TouchState* touchState,
1007 bool addOutsideTargets,
1008 bool addPortalWindows,
1009 bool ignoreDragWindow) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001010 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
1011 LOG_ALWAYS_FATAL(
1012 "Must provide a valid touch state if adding portal windows or outside targets");
1013 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001014 // Traverse windows from front to back to find touched window.
chaviw3277faf2021-05-19 16:45:23 -05001015 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
1016 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001017 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001018 continue;
1019 }
chaviw3277faf2021-05-19 16:45:23 -05001020 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001021 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +01001022 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001023
1024 if (windowInfo->visible) {
chaviw3277faf2021-05-19 16:45:23 -05001025 if (!flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
1026 bool isTouchModal = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
1027 !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001028 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001029 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001030 if (portalToDisplayId != ADISPLAY_ID_NONE &&
1031 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001032 if (addPortalWindows) {
1033 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001034 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001035 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001036 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001037 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001038 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001039 // Found window.
1040 return windowHandle;
1041 }
1042 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001043
chaviw3277faf2021-05-19 16:45:23 -05001044 if (addOutsideTargets && flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001045 touchState->addOrUpdateWindow(windowHandle,
1046 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1047 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001048 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001049 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001050 }
1051 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001052 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001053}
1054
Garfield Tane84e6f92019-08-29 17:28:41 -07001055std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
chaviw3277faf2021-05-19 16:45:23 -05001056 int32_t displayId, const std::vector<sp<WindowInfoHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00001057 std::vector<TouchedMonitor> touchedMonitors;
1058
1059 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
1060 addGestureMonitors(monitors, touchedMonitors);
chaviw3277faf2021-05-19 16:45:23 -05001061 for (const sp<WindowInfoHandle>& portalWindow : portalWindows) {
1062 const WindowInfo* windowInfo = portalWindow->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001063 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001064 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
1065 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +00001066 }
1067 return touchedMonitors;
1068}
1069
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001070void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001071 const char* reason;
1072 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001073 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -08001074#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001075 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001076#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001077 reason = "inbound event was dropped because the policy consumed it";
1078 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001079 case DropReason::DISABLED:
1080 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001081 ALOGI("Dropped event because input dispatch is disabled.");
1082 }
1083 reason = "inbound event was dropped because input dispatch is disabled";
1084 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001085 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001086 ALOGI("Dropped event because of pending overdue app switch.");
1087 reason = "inbound event was dropped because of pending overdue app switch";
1088 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001089 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001090 ALOGI("Dropped event because the current application is not responding and the user "
1091 "has started interacting with a different application.");
1092 reason = "inbound event was dropped because the current application is not responding "
1093 "and the user has started interacting with a different application";
1094 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001095 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001096 ALOGI("Dropped event because it is stale.");
1097 reason = "inbound event was dropped because it is stale";
1098 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001099 case DropReason::NO_POINTER_CAPTURE:
1100 ALOGI("Dropped event because there is no window with Pointer Capture.");
1101 reason = "inbound event was dropped because there is no window with Pointer Capture";
1102 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001103 case DropReason::NOT_DROPPED: {
1104 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001105 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001106 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001107 }
1108
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001109 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001110 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001111 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1112 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001113 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001114 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001115 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001116 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1117 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001118 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1119 synthesizeCancelationEventsForAllConnectionsLocked(options);
1120 } else {
1121 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1122 synthesizeCancelationEventsForAllConnectionsLocked(options);
1123 }
1124 break;
1125 }
Chris Yef59a2f42020-10-16 12:55:26 -07001126 case EventEntry::Type::SENSOR: {
1127 break;
1128 }
arthurhungb89ccb02020-12-30 16:19:01 +08001129 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1130 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001131 break;
1132 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001133 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001134 case EventEntry::Type::CONFIGURATION_CHANGED:
1135 case EventEntry::Type::DEVICE_RESET: {
Chris Yef59a2f42020-10-16 12:55:26 -07001136 LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001137 break;
1138 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001139 }
1140}
1141
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001142static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001143 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1144 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001145}
1146
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001147bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1148 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1149 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1150 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001151}
1152
1153bool InputDispatcher::isAppSwitchPendingLocked() {
1154 return mAppSwitchDueTime != LONG_LONG_MAX;
1155}
1156
1157void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1158 mAppSwitchDueTime = LONG_LONG_MAX;
1159
1160#if DEBUG_APP_SWITCH
1161 if (handled) {
1162 ALOGD("App switch has arrived.");
1163 } else {
1164 ALOGD("App switch was abandoned.");
1165 }
1166#endif
1167}
1168
Michael Wrightd02c5b62014-02-10 15:10:22 -08001169bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001170 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001171}
1172
1173bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001174 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001175 return false;
1176 }
1177
1178 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001179 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001180 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001181 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001182 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001183
1184 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001185 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001186 return true;
1187}
1188
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001189void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1190 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001191}
1192
1193void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001194 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001195 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001196 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001197 releaseInboundEventLocked(entry);
1198 }
1199 traceInboundQueueLengthLocked();
1200}
1201
1202void InputDispatcher::releasePendingEventLocked() {
1203 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001204 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001205 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001206 }
1207}
1208
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001209void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001210 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001211 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001212#if DEBUG_DISPATCH_CYCLE
1213 ALOGD("Injected inbound event was dropped.");
1214#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001215 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001216 }
1217 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001218 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001219 }
1220 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001221}
1222
1223void InputDispatcher::resetKeyRepeatLocked() {
1224 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001225 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001226 }
1227}
1228
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001229std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1230 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001231
Michael Wright2e732952014-09-24 13:26:59 -07001232 uint32_t policyFlags = entry->policyFlags &
1233 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001234
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001235 std::shared_ptr<KeyEntry> newEntry =
1236 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1237 entry->source, entry->displayId, policyFlags, entry->action,
1238 entry->flags, entry->keyCode, entry->scanCode,
1239 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001240
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001241 newEntry->syntheticRepeat = true;
1242 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001243 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001244 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001245}
1246
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001247bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001248 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001249#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001250 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001251#endif
1252
1253 // Reset key repeating in case a keyboard device was added or removed or something.
1254 resetKeyRepeatLocked();
1255
1256 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001257 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1258 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001259 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001260 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001261 return true;
1262}
1263
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001264bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1265 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001266#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001267 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1268 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001269#endif
1270
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001271 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001272 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001273 synthesizeCancelationEventsForAllConnectionsLocked(options);
1274 return true;
1275}
1276
Vishnu Nairad321cd2020-08-20 16:40:21 -07001277void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001278 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001279 if (mPendingEvent != nullptr) {
1280 // Move the pending event to the front of the queue. This will give the chance
1281 // for the pending event to get dispatched to the newly focused window
1282 mInboundQueue.push_front(mPendingEvent);
1283 mPendingEvent = nullptr;
1284 }
1285
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001286 std::unique_ptr<FocusEntry> focusEntry =
1287 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1288 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001289
1290 // This event should go to the front of the queue, but behind all other focus events
1291 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001292 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001293 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001294 [](const std::shared_ptr<EventEntry>& event) {
1295 return event->type == EventEntry::Type::FOCUS;
1296 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001297
1298 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001299 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001300}
1301
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001302void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001303 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001304 if (channel == nullptr) {
1305 return; // Window has gone away
1306 }
1307 InputTarget target;
1308 target.inputChannel = channel;
1309 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1310 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001311 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1312 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001313 std::string reason = std::string("reason=").append(entry->reason);
1314 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001315 dispatchEventLocked(currentTime, entry, {target});
1316}
1317
Prabir Pradhan99987712020-11-10 18:43:05 -08001318void InputDispatcher::dispatchPointerCaptureChangedLocked(
1319 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1320 DropReason& dropReason) {
Prabir Pradhanac483a62021-08-06 14:01:18 +00001321 dropReason = DropReason::NOT_DROPPED;
1322
Prabir Pradhan99987712020-11-10 18:43:05 -08001323 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001324 sp<IBinder> token;
Prabir Pradhanac483a62021-08-06 14:01:18 +00001325
1326 if (entry->pointerCaptureRequest.enable) {
1327 // Enable Pointer Capture.
1328 if (haveWindowWithPointerCapture &&
1329 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1330 LOG_ALWAYS_FATAL("This request to enable Pointer Capture has already been dispatched "
1331 "to the window.");
1332 }
1333 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001334 // This can happen if a window requests capture and immediately releases capture.
1335 ALOGW("No window requested Pointer Capture.");
Prabir Pradhanac483a62021-08-06 14:01:18 +00001336 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001337 return;
1338 }
Prabir Pradhanac483a62021-08-06 14:01:18 +00001339 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1340 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1341 return;
1342 }
1343
Vishnu Nairc519ff72021-01-21 08:23:08 -08001344 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001345 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1346 mWindowTokenWithPointerCapture = token;
1347 } else {
Prabir Pradhanac483a62021-08-06 14:01:18 +00001348 // Disable Pointer Capture.
1349 // We do not check if the sequence number matches for requests to disable Pointer Capture
1350 // for two reasons:
1351 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1352 // to disable capture with the same sequence number: one generated by
1353 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1354 // Capture being disabled in InputReader.
1355 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1356 // actual Pointer Capture state that affects events being generated by input devices is
1357 // in InputReader.
1358 if (!haveWindowWithPointerCapture) {
1359 // Pointer capture was already forcefully disabled because of focus change.
1360 dropReason = DropReason::NOT_DROPPED;
1361 return;
1362 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001363 token = mWindowTokenWithPointerCapture;
1364 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhanac483a62021-08-06 14:01:18 +00001365 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001366 setPointerCaptureLocked(false);
1367 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001368 }
1369
1370 auto channel = getInputChannelLocked(token);
1371 if (channel == nullptr) {
1372 // Window has gone away, clean up Pointer Capture state.
1373 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhanac483a62021-08-06 14:01:18 +00001374 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001375 setPointerCaptureLocked(false);
1376 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001377 return;
1378 }
1379 InputTarget target;
1380 target.inputChannel = channel;
1381 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1382 entry->dispatchInProgress = true;
1383 dispatchEventLocked(currentTime, entry, {target});
1384
1385 dropReason = DropReason::NOT_DROPPED;
1386}
1387
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001388bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001389 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001390 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001391 if (!entry->dispatchInProgress) {
1392 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1393 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1394 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1395 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001396 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001397 // We have seen two identical key downs in a row which indicates that the device
1398 // driver is automatically generating key repeats itself. We take note of the
1399 // repeat here, but we disable our own next key repeat timer since it is clear that
1400 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001401 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1402 // Make sure we don't get key down from a different device. If a different
1403 // device Id has same key pressed down, the new device Id will replace the
1404 // current one to hold the key repeat with repeat count reset.
1405 // In the future when got a KEY_UP on the device id, drop it and do not
1406 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001407 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1408 resetKeyRepeatLocked();
1409 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1410 } else {
1411 // Not a repeat. Save key down state in case we do see a repeat later.
1412 resetKeyRepeatLocked();
1413 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1414 }
1415 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001416 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1417 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001418 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001419#if DEBUG_INBOUND_EVENT_DETAILS
1420 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1421#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001422 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001423 resetKeyRepeatLocked();
1424 }
1425
1426 if (entry->repeatCount == 1) {
1427 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1428 } else {
1429 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1430 }
1431
1432 entry->dispatchInProgress = true;
1433
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001434 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001435 }
1436
1437 // Handle case where the policy asked us to try again later last time.
1438 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1439 if (currentTime < entry->interceptKeyWakeupTime) {
1440 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1441 *nextWakeupTime = entry->interceptKeyWakeupTime;
1442 }
1443 return false; // wait until next wakeup
1444 }
1445 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1446 entry->interceptKeyWakeupTime = 0;
1447 }
1448
1449 // Give the policy a chance to intercept the key.
1450 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1451 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001452 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001453 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001454 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001455 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001456 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001457 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001458 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001459 return false; // wait for the command to run
1460 } else {
1461 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1462 }
1463 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001464 if (*dropReason == DropReason::NOT_DROPPED) {
1465 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001466 }
1467 }
1468
1469 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001470 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001471 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001472 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1473 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001474 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001475 return true;
1476 }
1477
1478 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001479 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001480 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001481 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001482 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001483 return false;
1484 }
1485
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001486 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001487 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001488 return true;
1489 }
1490
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001491 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001492 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001493
1494 // Dispatch the key.
1495 dispatchEventLocked(currentTime, entry, inputTargets);
1496 return true;
1497}
1498
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001499void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001500#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001501 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001502 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1503 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001504 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1505 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1506 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001507#endif
1508}
1509
Chris Yef59a2f42020-10-16 12:55:26 -07001510void InputDispatcher::doNotifySensorLockedInterruptible(CommandEntry* commandEntry) {
1511 mLock.unlock();
1512
1513 const std::shared_ptr<SensorEntry>& entry = commandEntry->sensorEntry;
1514 if (entry->accuracyChanged) {
1515 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1516 }
1517 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1518 entry->hwTimestamp, entry->values);
1519 mLock.lock();
1520}
1521
1522void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, std::shared_ptr<SensorEntry> entry,
1523 DropReason* dropReason, nsecs_t* nextWakeupTime) {
1524#if DEBUG_OUTBOUND_EVENT_DETAILS
1525 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1526 "source=0x%x, sensorType=%s",
1527 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Prabir Pradhanbe05b5b2021-02-24 16:39:43 -08001528 NamedEnum::string(entry->sensorType).c_str());
Chris Yef59a2f42020-10-16 12:55:26 -07001529#endif
1530 std::unique_ptr<CommandEntry> commandEntry =
1531 std::make_unique<CommandEntry>(&InputDispatcher::doNotifySensorLockedInterruptible);
1532 commandEntry->sensorEntry = entry;
1533 postCommandLocked(std::move(commandEntry));
1534}
1535
1536bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
1537#if DEBUG_OUTBOUND_EVENT_DETAILS
1538 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
1539 NamedEnum::string(sensorType).c_str());
1540#endif
1541 { // acquire lock
1542 std::scoped_lock _l(mLock);
1543
1544 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1545 std::shared_ptr<EventEntry> entry = *it;
1546 if (entry->type == EventEntry::Type::SENSOR) {
1547 it = mInboundQueue.erase(it);
1548 releaseInboundEventLocked(entry);
1549 }
1550 }
1551 }
1552 return true;
1553}
1554
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001555bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001556 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001557 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001558 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001559 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001560 entry->dispatchInProgress = true;
1561
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001562 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001563 }
1564
1565 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001566 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001567 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001568 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1569 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001570 return true;
1571 }
1572
1573 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1574
1575 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001576 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001577
1578 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001579 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001580 if (isPointerEvent) {
1581 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001582 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001583 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001584 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001585 } else {
1586 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001587 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001588 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001589 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001590 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001591 return false;
1592 }
1593
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001594 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001595 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001596 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1597 return true;
1598 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001599 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001600 CancelationOptions::Mode mode(isPointerEvent
1601 ? CancelationOptions::CANCEL_POINTER_EVENTS
1602 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1603 CancelationOptions options(mode, "input event injection failed");
1604 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605 return true;
1606 }
1607
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001608 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001609 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001610
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001611 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001612 std::unordered_map<int32_t, TouchState>::iterator it =
1613 mTouchStatesByDisplay.find(entry->displayId);
1614 if (it != mTouchStatesByDisplay.end()) {
1615 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001616 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001617 // The event has gone through these portal windows, so we add monitoring targets of
1618 // the corresponding displays as well.
1619 for (size_t i = 0; i < state.portalWindows.size(); i++) {
chaviw3277faf2021-05-19 16:45:23 -05001620 const WindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001621 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001622 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001623 }
1624 }
1625 }
1626 }
1627
Michael Wrightd02c5b62014-02-10 15:10:22 -08001628 // Dispatch the motion.
1629 if (conflictingPointerActions) {
1630 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001631 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001632 synthesizeCancelationEventsForAllConnectionsLocked(options);
1633 }
1634 dispatchEventLocked(currentTime, entry, inputTargets);
1635 return true;
1636}
1637
chaviw3277faf2021-05-19 16:45:23 -05001638void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001639 bool isExiting, const MotionEntry& motionEntry) {
1640 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1641 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1642 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1643 PointerCoords pointerCoords;
1644 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1645 pointerCoords.transform(windowHandle->getInfo()->transform);
1646
1647 std::unique_ptr<DragEntry> dragEntry =
1648 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1649 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1650 pointerCoords.getY());
1651
1652 enqueueInboundEventLocked(std::move(dragEntry));
1653}
1654
1655void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1656 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1657 if (channel == nullptr) {
1658 return; // Window has gone away
1659 }
1660 InputTarget target;
1661 target.inputChannel = channel;
1662 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1663 entry->dispatchInProgress = true;
1664 dispatchEventLocked(currentTime, entry, {target});
1665}
1666
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001667void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001668#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001669 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001670 ", policyFlags=0x%x, "
1671 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1672 "metaState=0x%x, buttonState=0x%x,"
1673 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001674 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1675 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1676 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001677
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001678 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001679 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001680 "x=%f, y=%f, pressure=%f, size=%f, "
1681 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1682 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001683 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1684 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1685 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1686 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1687 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1688 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1689 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1690 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1691 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1692 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001693 }
1694#endif
1695}
1696
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001697void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1698 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001699 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001700 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001701#if DEBUG_DISPATCH_CYCLE
1702 ALOGD("dispatchEventToCurrentInputTargets");
1703#endif
1704
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001705 updateInteractionTokensLocked(*eventEntry, inputTargets);
1706
Michael Wrightd02c5b62014-02-10 15:10:22 -08001707 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1708
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001709 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001710
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001711 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001712 sp<Connection> connection =
1713 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001714 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001715 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001716 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001717 if (DEBUG_FOCUS) {
1718 ALOGD("Dropping event delivery to target with channel '%s' because it "
1719 "is no longer registered with the input dispatcher.",
1720 inputTarget.inputChannel->getName().c_str());
1721 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001722 }
1723 }
1724}
1725
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001726void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1727 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1728 // If the policy decides to close the app, we will get a channel removal event via
1729 // unregisterInputChannel, and will clean up the connection that way. We are already not
1730 // sending new pointers to the connection when it blocked, but focused events will continue to
1731 // pile up.
1732 ALOGW("Canceling events for %s because it is unresponsive",
1733 connection->inputChannel->getName().c_str());
1734 if (connection->status == Connection::STATUS_NORMAL) {
1735 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1736 "application not responding");
1737 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001738 }
1739}
1740
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001741void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001742 if (DEBUG_FOCUS) {
1743 ALOGD("Resetting ANR timeouts.");
1744 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001745
1746 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001747 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001748 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001749}
1750
Tiger Huang721e26f2018-07-24 22:26:19 +08001751/**
1752 * Get the display id that the given event should go to. If this event specifies a valid display id,
1753 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1754 * Focused display is the display that the user most recently interacted with.
1755 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001756int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001757 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001758 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001759 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001760 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1761 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001762 break;
1763 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001764 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001765 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1766 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001767 break;
1768 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001769 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001770 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001771 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001772 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001773 case EventEntry::Type::SENSOR:
1774 case EventEntry::Type::DRAG: {
Chris Yef59a2f42020-10-16 12:55:26 -07001775 ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001776 return ADISPLAY_ID_NONE;
1777 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001778 }
1779 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1780}
1781
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001782bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1783 const char* focusedWindowName) {
1784 if (mAnrTracker.empty()) {
1785 // already processed all events that we waited for
1786 mKeyIsWaitingForEventsTimeout = std::nullopt;
1787 return false;
1788 }
1789
1790 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1791 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001792 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001793 mKeyIsWaitingForEventsTimeout = currentTime +
1794 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1795 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001796 return true;
1797 }
1798
1799 // We still have pending events, and already started the timer
1800 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1801 return true; // Still waiting
1802 }
1803
1804 // Waited too long, and some connection still hasn't processed all motions
1805 // Just send the key to the focused window
1806 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1807 focusedWindowName);
1808 mKeyIsWaitingForEventsTimeout = std::nullopt;
1809 return false;
1810}
1811
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001812InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1813 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1814 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001815 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001816
Tiger Huang721e26f2018-07-24 22:26:19 +08001817 int32_t displayId = getTargetDisplayId(entry);
chaviw3277faf2021-05-19 16:45:23 -05001818 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001819 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001820 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1821
Michael Wrightd02c5b62014-02-10 15:10:22 -08001822 // If there is no currently focused window and no focused application
1823 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001824 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1825 ALOGI("Dropping %s event because there is no focused window or focused application in "
1826 "display %" PRId32 ".",
Chris Yef59a2f42020-10-16 12:55:26 -07001827 NamedEnum::string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001828 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001829 }
1830
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001831 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1832 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1833 // start interacting with another application via touch (app switch). This code can be removed
1834 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1835 // an app is expected to have a focused window.
1836 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1837 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1838 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001839 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1840 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1841 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001842 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001843 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001844 ALOGW("Waiting because no window has focus but %s may eventually add a "
1845 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001846 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001847 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001848 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001849 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1850 // Already raised ANR. Drop the event
1851 ALOGE("Dropping %s event because there is no focused window",
Chris Yef59a2f42020-10-16 12:55:26 -07001852 NamedEnum::string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001853 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001854 } else {
1855 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001856 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001857 }
1858 }
1859
1860 // we have a valid, non-null focused window
1861 resetNoFocusedWindowTimeoutLocked();
1862
Michael Wrightd02c5b62014-02-10 15:10:22 -08001863 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001864 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001865 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001866 }
1867
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001868 if (focusedWindowHandle->getInfo()->paused) {
1869 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001870 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001871 }
1872
1873 // If the event is a key event, then we must wait for all previous events to
1874 // complete before delivering it because previous events may have the
1875 // side-effect of transferring focus to a different window and we want to
1876 // ensure that the following keys are sent to the new window.
1877 //
1878 // Suppose the user touches a button in a window then immediately presses "A".
1879 // If the button causes a pop-up window to appear then we want to ensure that
1880 // the "A" key is delivered to the new pop-up window. This is because users
1881 // often anticipate pending UI changes when typing on a keyboard.
1882 // To obtain this behavior, we must serialize key events with respect to all
1883 // prior input events.
1884 if (entry.type == EventEntry::Type::KEY) {
1885 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1886 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001887 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001888 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001889 }
1890
1891 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001892 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001893 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1894 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001895
1896 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001897 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001898}
1899
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001900/**
1901 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1902 * that are currently unresponsive.
1903 */
1904std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1905 const std::vector<TouchedMonitor>& monitors) const {
1906 std::vector<TouchedMonitor> responsiveMonitors;
1907 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1908 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1909 sp<Connection> connection = getConnectionLocked(
1910 monitor.monitor.inputChannel->getConnectionToken());
1911 if (connection == nullptr) {
1912 ALOGE("Could not find connection for monitor %s",
1913 monitor.monitor.inputChannel->getName().c_str());
1914 return false;
1915 }
1916 if (!connection->responsive) {
1917 ALOGW("Unresponsive monitor %s will not get the new gesture",
1918 connection->inputChannel->getName().c_str());
1919 return false;
1920 }
1921 return true;
1922 });
1923 return responsiveMonitors;
1924}
1925
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001926InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1927 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1928 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001929 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001930 enum InjectionPermission {
1931 INJECTION_PERMISSION_UNKNOWN,
1932 INJECTION_PERMISSION_GRANTED,
1933 INJECTION_PERMISSION_DENIED
1934 };
1935
Michael Wrightd02c5b62014-02-10 15:10:22 -08001936 // For security reasons, we defer updating the touch state until we are sure that
1937 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001938 int32_t displayId = entry.displayId;
1939 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001940 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1941
1942 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001943 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001944 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw3277faf2021-05-19 16:45:23 -05001945 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1946 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001947
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001948 // Copy current touch state into tempTouchState.
1949 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1950 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001951 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001952 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001953 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1954 mTouchStatesByDisplay.find(displayId);
1955 if (oldStateIt != mTouchStatesByDisplay.end()) {
1956 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001957 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001958 }
1959
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001960 bool isSplit = tempTouchState.split;
1961 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1962 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1963 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001964 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1965 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1966 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1967 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1968 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001969 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001970 bool wrongDevice = false;
1971 if (newGesture) {
1972 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001973 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001974 ALOGI("Dropping event because a pointer for a different device is already down "
1975 "in display %" PRId32,
1976 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001977 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001978 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001979 switchedDevice = false;
1980 wrongDevice = true;
1981 goto Failed;
1982 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001983 tempTouchState.reset();
1984 tempTouchState.down = down;
1985 tempTouchState.deviceId = entry.deviceId;
1986 tempTouchState.source = entry.source;
1987 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001988 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001989 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001990 ALOGI("Dropping move event because a pointer for a different device is already active "
1991 "in display %" PRId32,
1992 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001993 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001994 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001995 switchedDevice = false;
1996 wrongDevice = true;
1997 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001998 }
1999
2000 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2001 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2002
Garfield Tan00f511d2019-06-12 16:55:40 -07002003 int32_t x;
2004 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002005 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07002006 // Always dispatch mouse events to cursor position.
2007 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002008 x = int32_t(entry.xCursorPosition);
2009 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07002010 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002011 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
2012 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07002013 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002014 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07002015 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002016 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
2017 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00002018
2019 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002020 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00002021 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002022
Michael Wrightd02c5b62014-02-10 15:10:22 -08002023 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002024 if (newTouchedWindowHandle != nullptr &&
2025 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07002026 // New window supports splitting, but we should never split mouse events.
2027 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002028 } else if (isSplit) {
2029 // New window does not support splitting but we have already split events.
2030 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002031 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002032 }
2033
2034 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002035 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002036 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002037 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002038 }
2039
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002040 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
2041 ALOGI("Not sending touch event to %s because it is paused",
2042 newTouchedWindowHandle->getName().c_str());
2043 newTouchedWindowHandle = nullptr;
2044 }
2045
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002046 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002047 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002048 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
2049 if (!isResponsive) {
2050 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002051 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
2052 newTouchedWindowHandle = nullptr;
2053 }
2054 }
2055
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002056 // Drop events that can't be trusted due to occlusion
2057 if (newTouchedWindowHandle != nullptr &&
2058 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2059 TouchOcclusionInfo occlusionInfo =
2060 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002061 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002062 if (DEBUG_TOUCH_OCCLUSION) {
2063 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2064 for (const auto& log : occlusionInfo.debugInfo) {
2065 ALOGD("%s", log.c_str());
2066 }
2067 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002068 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
2069 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2070 ALOGW("Dropping untrusted touch event due to %s/%d",
2071 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2072 newTouchedWindowHandle = nullptr;
2073 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002074 }
2075 }
2076
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002077 // Also don't send the new touch event to unresponsive gesture monitors
2078 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
2079
Michael Wright3dd60e22019-03-27 22:06:44 +00002080 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
2081 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002082 "(%d, %d) in display %" PRId32 ".",
2083 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002084 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00002085 goto Failed;
2086 }
2087
2088 if (newTouchedWindowHandle != nullptr) {
2089 // Set target flags.
2090 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
2091 if (isSplit) {
2092 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002093 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002094 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2095 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2096 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2097 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2098 }
2099
2100 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07002101 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2102 newHoverWindowHandle = nullptr;
2103 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002104 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002105 }
2106
2107 // Update the temporary touch state.
2108 BitSet32 pointerIds;
2109 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002110 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002111 pointerIds.markBit(pointerId);
2112 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002113 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002114 }
2115
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002116 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002117 } else {
2118 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2119
2120 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002121 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002122 if (DEBUG_FOCUS) {
2123 ALOGD("Dropping event because the pointer is not down or we previously "
2124 "dropped the pointer down event in display %" PRId32,
2125 displayId);
2126 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002127 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002128 goto Failed;
2129 }
2130
arthurhung6d4bed92021-03-17 11:59:33 +08002131 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002132
Michael Wrightd02c5b62014-02-10 15:10:22 -08002133 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002134 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002135 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002136 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2137 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002138
chaviw3277faf2021-05-19 16:45:23 -05002139 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002140 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002141 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002142 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2143 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002144 if (DEBUG_FOCUS) {
2145 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2146 oldTouchedWindowHandle->getName().c_str(),
2147 newTouchedWindowHandle->getName().c_str(), displayId);
2148 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002149 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002150 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2151 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2152 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002153
2154 // Make a slippery entrance into the new window.
2155 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2156 isSplit = true;
2157 }
2158
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002159 int32_t targetFlags =
2160 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002161 if (isSplit) {
2162 targetFlags |= InputTarget::FLAG_SPLIT;
2163 }
2164 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2165 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002166 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2167 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002168 }
2169
2170 BitSet32 pointerIds;
2171 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002172 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002173 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002174 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002175 }
2176 }
2177 }
2178
2179 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002180 // Let the previous window know that the hover sequence is over, unless we already did it
2181 // when dispatching it as is to newTouchedWindowHandle.
2182 if (mLastHoverWindowHandle != nullptr &&
2183 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2184 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002185#if DEBUG_HOVER
2186 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002187 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002188#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002189 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2190 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002191 }
2192
Garfield Tandf26e862020-07-01 20:18:19 -07002193 // Let the new window know that the hover sequence is starting, unless we already did it
2194 // when dispatching it as is to newTouchedWindowHandle.
2195 if (newHoverWindowHandle != nullptr &&
2196 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2197 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002198#if DEBUG_HOVER
2199 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002200 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002201#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002202 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2203 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2204 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002205 }
2206 }
2207
2208 // Check permission to inject into all touched foreground windows and ensure there
2209 // is at least one touched foreground window.
2210 {
2211 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002212 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002213 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2214 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002215 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002216 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002217 injectionPermission = INJECTION_PERMISSION_DENIED;
2218 goto Failed;
2219 }
2220 }
2221 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002222 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002223 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002224 ALOGI("Dropping event because there is no touched foreground window in display "
2225 "%" PRId32 " or gesture monitor to receive it.",
2226 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002227 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002228 goto Failed;
2229 }
2230
2231 // Permission granted to injection into all touched foreground windows.
2232 injectionPermission = INJECTION_PERMISSION_GRANTED;
2233 }
2234
2235 // Check whether windows listening for outside touches are owned by the same UID. If it is
2236 // set the policy flag that we will not reveal coordinate information to this window.
2237 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw3277faf2021-05-19 16:45:23 -05002238 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002239 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002240 if (foregroundWindowHandle) {
2241 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002242 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002243 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw3277faf2021-05-19 16:45:23 -05002244 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2245 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2246 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002247 InputTarget::FLAG_ZERO_COORDS,
2248 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002249 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002250 }
2251 }
2252 }
2253 }
2254
Michael Wrightd02c5b62014-02-10 15:10:22 -08002255 // If this is the first pointer going down and the touched window has a wallpaper
2256 // then also add the touched wallpaper windows so they are locked in for the duration
2257 // of the touch gesture.
2258 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2259 // engine only supports touch events. We would need to add a mechanism similar
2260 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2261 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw3277faf2021-05-19 16:45:23 -05002262 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002263 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002264 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
chaviw3277faf2021-05-19 16:45:23 -05002265 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002266 getWindowHandlesLocked(displayId);
chaviw3277faf2021-05-19 16:45:23 -05002267 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2268 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002269 if (info->displayId == displayId &&
chaviw3277faf2021-05-19 16:45:23 -05002270 windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002271 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002272 .addOrUpdateWindow(windowHandle,
2273 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2274 InputTarget::
2275 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2276 InputTarget::FLAG_DISPATCH_AS_IS,
2277 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002278 }
2279 }
2280 }
2281 }
2282
2283 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002284 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002285
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002286 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002287 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002288 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002289 }
2290
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002291 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002292 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002293 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002294 }
2295
Michael Wrightd02c5b62014-02-10 15:10:22 -08002296 // Drop the outside or hover touch windows since we will not care about them
2297 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002298 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002299
2300Failed:
2301 // Check injection permission once and for all.
2302 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002303 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002304 injectionPermission = INJECTION_PERMISSION_GRANTED;
2305 } else {
2306 injectionPermission = INJECTION_PERMISSION_DENIED;
2307 }
2308 }
2309
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002310 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2311 return injectionResult;
2312 }
2313
Michael Wrightd02c5b62014-02-10 15:10:22 -08002314 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002315 if (!wrongDevice) {
2316 if (switchedDevice) {
2317 if (DEBUG_FOCUS) {
2318 ALOGD("Conflicting pointer actions: Switched to a different device.");
2319 }
2320 *outConflictingPointerActions = true;
2321 }
2322
2323 if (isHoverAction) {
2324 // Started hovering, therefore no longer down.
2325 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002326 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002327 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2328 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002329 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002330 *outConflictingPointerActions = true;
2331 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002332 tempTouchState.reset();
2333 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2334 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2335 tempTouchState.deviceId = entry.deviceId;
2336 tempTouchState.source = entry.source;
2337 tempTouchState.displayId = displayId;
2338 }
2339 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2340 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2341 // All pointers up or canceled.
2342 tempTouchState.reset();
2343 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2344 // First pointer went down.
2345 if (oldState && oldState->down) {
2346 if (DEBUG_FOCUS) {
2347 ALOGD("Conflicting pointer actions: Down received while already down.");
2348 }
2349 *outConflictingPointerActions = true;
2350 }
2351 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2352 // One pointer went up.
2353 if (isSplit) {
2354 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2355 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002356
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002357 for (size_t i = 0; i < tempTouchState.windows.size();) {
2358 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2359 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2360 touchedWindow.pointerIds.clearBit(pointerId);
2361 if (touchedWindow.pointerIds.isEmpty()) {
2362 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2363 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002364 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002365 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002366 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002367 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002368 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002369 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002370
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002371 // Save changes unless the action was scroll in which case the temporary touch
2372 // state was only valid for this one action.
2373 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2374 if (tempTouchState.displayId >= 0) {
2375 mTouchStatesByDisplay[displayId] = tempTouchState;
2376 } else {
2377 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002378 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002379 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002380
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002381 // Update hover state.
2382 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002383 }
2384
Michael Wrightd02c5b62014-02-10 15:10:22 -08002385 return injectionResult;
2386}
2387
arthurhung6d4bed92021-03-17 11:59:33 +08002388void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
chaviw3277faf2021-05-19 16:45:23 -05002389 const sp<WindowInfoHandle> dropWindow =
arthurhung6d4bed92021-03-17 11:59:33 +08002390 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
2391 false /*addOutsideTargets*/, false /*addPortalWindows*/,
2392 true /*ignoreDragWindow*/);
2393 if (dropWindow) {
2394 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
2395 notifyDropWindowLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002396 } else {
2397 notifyDropWindowLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002398 }
2399 mDragState.reset();
2400}
2401
2402void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2403 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002404 return;
2405 }
2406
arthurhung6d4bed92021-03-17 11:59:33 +08002407 if (!mDragState->isStartDrag) {
2408 mDragState->isStartDrag = true;
2409 mDragState->isStylusButtonDownAtStart =
2410 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2411 }
2412
arthurhungb89ccb02020-12-30 16:19:01 +08002413 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2414 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2415 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2416 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002417 // Handle the special case : stylus button no longer pressed.
2418 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2419 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2420 finishDragAndDrop(entry.displayId, x, y);
2421 return;
2422 }
2423
chaviw3277faf2021-05-19 16:45:23 -05002424 const sp<WindowInfoHandle> hoverWindowHandle =
arthurhung6d4bed92021-03-17 11:59:33 +08002425 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
arthurhungb89ccb02020-12-30 16:19:01 +08002426 false /*addOutsideTargets*/, false /*addPortalWindows*/,
2427 true /*ignoreDragWindow*/);
2428 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002429 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2430 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2431 if (mDragState->dragHoverWindowHandle != nullptr) {
2432 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2433 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002434 }
arthurhung6d4bed92021-03-17 11:59:33 +08002435 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002436 }
2437 // enqueue drag location if needed.
2438 if (hoverWindowHandle != nullptr) {
2439 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2440 }
arthurhung6d4bed92021-03-17 11:59:33 +08002441 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2442 finishDragAndDrop(entry.displayId, x, y);
2443 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Arthur Hung6d0571e2021-04-09 20:18:16 +08002444 notifyDropWindowLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002445 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002446 }
2447}
2448
chaviw3277faf2021-05-19 16:45:23 -05002449void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002450 int32_t targetFlags, BitSet32 pointerIds,
2451 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002452 std::vector<InputTarget>::iterator it =
2453 std::find_if(inputTargets.begin(), inputTargets.end(),
2454 [&windowHandle](const InputTarget& inputTarget) {
2455 return inputTarget.inputChannel->getConnectionToken() ==
2456 windowHandle->getToken();
2457 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002458
chaviw3277faf2021-05-19 16:45:23 -05002459 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002460
2461 if (it == inputTargets.end()) {
2462 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002463 std::shared_ptr<InputChannel> inputChannel =
2464 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002465 if (inputChannel == nullptr) {
2466 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2467 return;
2468 }
2469 inputTarget.inputChannel = inputChannel;
2470 inputTarget.flags = targetFlags;
2471 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Evan Rosky09576692021-07-01 12:22:09 -07002472 inputTarget.displayOrientation = windowInfo->displayOrientation;
Evan Rosky84f07f02021-04-16 10:42:42 -07002473 inputTarget.displaySize =
Evan Rosky44edce92021-05-14 18:09:55 -07002474 int2(windowHandle->getInfo()->displayWidth, windowHandle->getInfo()->displayHeight);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002475 inputTargets.push_back(inputTarget);
2476 it = inputTargets.end() - 1;
2477 }
2478
2479 ALOG_ASSERT(it->flags == targetFlags);
2480 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2481
chaviw1ff3d1e2020-07-01 15:53:47 -07002482 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002483}
2484
Michael Wright3dd60e22019-03-27 22:06:44 +00002485void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002486 int32_t displayId, float xOffset,
2487 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002488 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2489 mGlobalMonitorsByDisplay.find(displayId);
2490
2491 if (it != mGlobalMonitorsByDisplay.end()) {
2492 const std::vector<Monitor>& monitors = it->second;
2493 for (const Monitor& monitor : monitors) {
2494 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002495 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002496 }
2497}
2498
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002499void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2500 float yOffset,
2501 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002502 InputTarget target;
2503 target.inputChannel = monitor.inputChannel;
2504 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002505 ui::Transform t;
2506 t.set(xOffset, yOffset);
2507 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002508 inputTargets.push_back(target);
2509}
2510
chaviw3277faf2021-05-19 16:45:23 -05002511bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002512 const InjectionState* injectionState) {
2513 if (injectionState &&
2514 (windowHandle == nullptr ||
2515 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2516 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002517 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002518 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002519 "owned by uid %d",
2520 injectionState->injectorPid, injectionState->injectorUid,
2521 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002522 } else {
2523 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002524 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002525 }
2526 return false;
2527 }
2528 return true;
2529}
2530
Robert Carrc9bf1d32020-04-13 17:21:08 -07002531/**
2532 * Indicate whether one window handle should be considered as obscuring
2533 * another window handle. We only check a few preconditions. Actually
2534 * checking the bounds is left to the caller.
2535 */
chaviw3277faf2021-05-19 16:45:23 -05002536static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2537 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002538 // Compare by token so cloned layers aren't counted
2539 if (haveSameToken(windowHandle, otherHandle)) {
2540 return false;
2541 }
2542 auto info = windowHandle->getInfo();
2543 auto otherInfo = otherHandle->getInfo();
2544 if (!otherInfo->visible) {
2545 return false;
chaviw3277faf2021-05-19 16:45:23 -05002546 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002547 // Those act as if they were invisible, so we don't need to flag them.
2548 // We do want to potentially flag touchable windows even if they have 0
2549 // opacity, since they can consume touches and alter the effects of the
2550 // user interaction (eg. apps that rely on
2551 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2552 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2553 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002554 } else if (info->ownerUid == otherInfo->ownerUid) {
2555 // If ownerUid is the same we don't generate occlusion events as there
2556 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002557 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002558 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002559 return false;
2560 } else if (otherInfo->displayId != info->displayId) {
2561 return false;
2562 }
2563 return true;
2564}
2565
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002566/**
2567 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2568 * untrusted, one should check:
2569 *
2570 * 1. If result.hasBlockingOcclusion is true.
2571 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2572 * BLOCK_UNTRUSTED.
2573 *
2574 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2575 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2576 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2577 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2578 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2579 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2580 *
2581 * If neither of those is true, then it means the touch can be allowed.
2582 */
2583InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw3277faf2021-05-19 16:45:23 -05002584 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2585 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002586 int32_t displayId = windowInfo->displayId;
chaviw3277faf2021-05-19 16:45:23 -05002587 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002588 TouchOcclusionInfo info;
2589 info.hasBlockingOcclusion = false;
2590 info.obscuringOpacity = 0;
2591 info.obscuringUid = -1;
2592 std::map<int32_t, float> opacityByUid;
chaviw3277faf2021-05-19 16:45:23 -05002593 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002594 if (windowHandle == otherHandle) {
2595 break; // All future windows are below us. Exit early.
2596 }
chaviw3277faf2021-05-19 16:45:23 -05002597 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002598 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2599 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002600 if (DEBUG_TOUCH_OCCLUSION) {
2601 info.debugInfo.push_back(
2602 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2603 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002604 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2605 // we perform the checks below to see if the touch can be propagated or not based on the
2606 // window's touch occlusion mode
2607 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2608 info.hasBlockingOcclusion = true;
2609 info.obscuringUid = otherInfo->ownerUid;
2610 info.obscuringPackage = otherInfo->packageName;
2611 break;
2612 }
2613 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2614 uint32_t uid = otherInfo->ownerUid;
2615 float opacity =
2616 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2617 // Given windows A and B:
2618 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2619 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2620 opacityByUid[uid] = opacity;
2621 if (opacity > info.obscuringOpacity) {
2622 info.obscuringOpacity = opacity;
2623 info.obscuringUid = uid;
2624 info.obscuringPackage = otherInfo->packageName;
2625 }
2626 }
2627 }
2628 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002629 if (DEBUG_TOUCH_OCCLUSION) {
2630 info.debugInfo.push_back(
2631 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2632 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002633 return info;
2634}
2635
chaviw3277faf2021-05-19 16:45:23 -05002636std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002637 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002638 return StringPrintf(INDENT2
2639 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2640 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2641 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2642 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002643 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002644 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002645 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002646 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2647 info->frameTop, info->frameRight, info->frameBottom,
2648 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002649 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2650 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2651 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002652}
2653
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002654bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2655 if (occlusionInfo.hasBlockingOcclusion) {
2656 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2657 occlusionInfo.obscuringUid);
2658 return false;
2659 }
2660 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2661 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2662 "%.2f, maximum allowed = %.2f)",
2663 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2664 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2665 return false;
2666 }
2667 return true;
2668}
2669
chaviw3277faf2021-05-19 16:45:23 -05002670bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002671 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002672 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw3277faf2021-05-19 16:45:23 -05002673 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2674 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002675 if (windowHandle == otherHandle) {
2676 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002677 }
chaviw3277faf2021-05-19 16:45:23 -05002678 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002679 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002680 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002681 return true;
2682 }
2683 }
2684 return false;
2685}
2686
chaviw3277faf2021-05-19 16:45:23 -05002687bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002688 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw3277faf2021-05-19 16:45:23 -05002689 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2690 const WindowInfo* windowInfo = windowHandle->getInfo();
2691 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002692 if (windowHandle == otherHandle) {
2693 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002694 }
chaviw3277faf2021-05-19 16:45:23 -05002695 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002696 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002697 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002698 return true;
2699 }
2700 }
2701 return false;
2702}
2703
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002704std::string InputDispatcher::getApplicationWindowLabel(
chaviw3277faf2021-05-19 16:45:23 -05002705 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002706 if (applicationHandle != nullptr) {
2707 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002708 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002709 } else {
2710 return applicationHandle->getName();
2711 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002712 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002713 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002714 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002715 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002716 }
2717}
2718
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002719void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002720 if (eventEntry.type == EventEntry::Type::FOCUS ||
arthurhungb89ccb02020-12-30 16:19:01 +08002721 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED ||
2722 eventEntry.type == EventEntry::Type::DRAG) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002723 // Focus or pointer capture changed events are passed to apps, but do not represent user
2724 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002725 return;
2726 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002727 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw3277faf2021-05-19 16:45:23 -05002728 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002729 if (focusedWindowHandle != nullptr) {
chaviw3277faf2021-05-19 16:45:23 -05002730 const WindowInfo* info = focusedWindowHandle->getInfo();
2731 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002732#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002733 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002734#endif
2735 return;
2736 }
2737 }
2738
2739 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002740 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002741 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002742 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2743 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002744 return;
2745 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002746
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002747 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002748 eventType = USER_ACTIVITY_EVENT_TOUCH;
2749 }
2750 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002751 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002752 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002753 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2754 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002755 return;
2756 }
2757 eventType = USER_ACTIVITY_EVENT_BUTTON;
2758 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002759 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002760 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002761 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002762 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002763 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08002764 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2765 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002766 LOG_ALWAYS_FATAL("%s events are not user activity",
Chris Yef59a2f42020-10-16 12:55:26 -07002767 NamedEnum::string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002768 break;
2769 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002770 }
2771
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002772 std::unique_ptr<CommandEntry> commandEntry =
2773 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002774 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002775 commandEntry->userActivityEventType = eventType;
Sean Stoutb4e0a592021-02-23 07:34:53 -08002776 commandEntry->displayId = displayId;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002777 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002778}
2779
2780void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002781 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002782 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002783 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002784 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002785 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002786 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002787 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002788 ATRACE_NAME(message.c_str());
2789 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002790#if DEBUG_DISPATCH_CYCLE
2791 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002792 "globalScaleFactor=%f, pointerIds=0x%x %s",
2793 connection->getInputChannelName().c_str(), inputTarget.flags,
2794 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2795 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002796#endif
2797
2798 // Skip this event if the connection status is not normal.
2799 // We don't want to enqueue additional outbound events if the connection is broken.
2800 if (connection->status != Connection::STATUS_NORMAL) {
2801#if DEBUG_DISPATCH_CYCLE
2802 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002803 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002804#endif
2805 return;
2806 }
2807
2808 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002809 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2810 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2811 "Entry type %s should not have FLAG_SPLIT",
Chris Yef59a2f42020-10-16 12:55:26 -07002812 NamedEnum::string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002813
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002814 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002815 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002816 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002817 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002818 if (!splitMotionEntry) {
2819 return; // split event was dropped
2820 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002821 if (DEBUG_FOCUS) {
2822 ALOGD("channel '%s' ~ Split motion event.",
2823 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002824 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002825 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002826 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2827 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002828 return;
2829 }
2830 }
2831
2832 // Not splitting. Enqueue dispatch entries for the event as is.
2833 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2834}
2835
2836void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002837 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002838 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002839 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002840 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002841 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002842 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002843 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002844 ATRACE_NAME(message.c_str());
2845 }
2846
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002847 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002848
2849 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002850 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002851 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002852 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002853 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002854 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002855 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002856 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002857 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002858 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002859 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002860 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002861 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002862
2863 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002864 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002865 startDispatchCycleLocked(currentTime, connection);
2866 }
2867}
2868
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002869void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002870 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002871 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002872 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002873 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002874 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2875 connection->getInputChannelName().c_str(),
2876 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002877 ATRACE_NAME(message.c_str());
2878 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002879 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002880 if (!(inputTargetFlags & dispatchMode)) {
2881 return;
2882 }
2883 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2884
2885 // This is a new event.
2886 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002887 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002888 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002889
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002890 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2891 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002892 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002893 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002894 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002895 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002896 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002897 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002898 dispatchEntry->resolvedAction = keyEntry.action;
2899 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002900
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002901 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2902 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002903#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002904 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2905 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002906#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002907 return; // skip the inconsistent event
2908 }
2909 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002910 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002911
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002912 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002913 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002914 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2915 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2916 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2917 static_cast<int32_t>(IdGenerator::Source::OTHER);
2918 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002919 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2920 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2921 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2922 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2923 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2924 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2925 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2926 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2927 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2928 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2929 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002930 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002931 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002932 }
2933 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002934 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2935 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002936#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002937 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2938 "event",
2939 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002940#endif
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00002941 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
2942 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002943 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2944 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002945
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002946 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002947 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2948 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2949 }
2950 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2951 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2952 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002953
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002954 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2955 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002956#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002957 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2958 "event",
2959 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002960#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002961 return; // skip the inconsistent event
2962 }
2963
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002964 dispatchEntry->resolvedEventId =
2965 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2966 ? mIdGenerator.nextId()
2967 : motionEntry.id;
2968 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2969 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2970 ") to MotionEvent(id=0x%" PRIx32 ").",
2971 motionEntry.id, dispatchEntry->resolvedEventId);
2972 ATRACE_NAME(message.c_str());
2973 }
2974
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08002975 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
2976 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
2977 // Skip reporting pointer down outside focus to the policy.
2978 break;
2979 }
2980
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002981 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002982 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002983
2984 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002985 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002986 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08002987 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2988 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002989 break;
2990 }
Chris Yef59a2f42020-10-16 12:55:26 -07002991 case EventEntry::Type::SENSOR: {
2992 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
2993 break;
2994 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002995 case EventEntry::Type::CONFIGURATION_CHANGED:
2996 case EventEntry::Type::DEVICE_RESET: {
2997 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chris Yef59a2f42020-10-16 12:55:26 -07002998 NamedEnum::string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002999 break;
3000 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003001 }
3002
3003 // Remember that we are waiting for this dispatch to complete.
3004 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003005 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003006 }
3007
3008 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003009 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003010 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003011}
3012
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003013/**
3014 * This function is purely for debugging. It helps us understand where the user interaction
3015 * was taking place. For example, if user is touching launcher, we will see a log that user
3016 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3017 * We will see both launcher and wallpaper in that list.
3018 * Once the interaction with a particular set of connections starts, no new logs will be printed
3019 * until the set of interacted connections changes.
3020 *
3021 * The following items are skipped, to reduce the logspam:
3022 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3023 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3024 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3025 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3026 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003027 */
3028void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3029 const std::vector<InputTarget>& targets) {
3030 // Skip ACTION_UP events, and all events other than keys and motions
3031 if (entry.type == EventEntry::Type::KEY) {
3032 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3033 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3034 return;
3035 }
3036 } else if (entry.type == EventEntry::Type::MOTION) {
3037 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3038 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3039 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3040 return;
3041 }
3042 } else {
3043 return; // Not a key or a motion
3044 }
3045
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003046 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003047 std::vector<sp<Connection>> newConnections;
3048 for (const InputTarget& target : targets) {
3049 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3050 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3051 continue; // Skip windows that receive ACTION_OUTSIDE
3052 }
3053
3054 sp<IBinder> token = target.inputChannel->getConnectionToken();
3055 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003056 if (connection == nullptr) {
3057 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003058 }
3059 newConnectionTokens.insert(std::move(token));
3060 newConnections.emplace_back(connection);
3061 }
3062 if (newConnectionTokens == mInteractionConnectionTokens) {
3063 return; // no change
3064 }
3065 mInteractionConnectionTokens = newConnectionTokens;
3066
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003067 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003068 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003069 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003070 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003071 std::string message = "Interaction with: " + targetList;
3072 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003073 message += "<none>";
3074 }
3075 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3076}
3077
chaviwfd6d3512019-03-25 13:23:49 -07003078void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003079 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003080 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003081 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3082 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003083 return;
3084 }
3085
Vishnu Nairc519ff72021-01-21 08:23:08 -08003086 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003087 if (focusedToken == token) {
3088 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003089 return;
3090 }
3091
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07003092 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
3093 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003094 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07003095 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003096}
3097
3098void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003099 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003100 if (ATRACE_ENABLED()) {
3101 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003102 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003103 ATRACE_NAME(message.c_str());
3104 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003105#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003106 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003107#endif
3108
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003109 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3110 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003111 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003112 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003113 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003114 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003115
3116 // Publish the event.
3117 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003118 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3119 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003120 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003121 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3122 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003123
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003124 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003125 status = connection->inputPublisher
3126 .publishKeyEvent(dispatchEntry->seq,
3127 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3128 keyEntry.source, keyEntry.displayId,
3129 std::move(hmac), dispatchEntry->resolvedAction,
3130 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3131 keyEntry.scanCode, keyEntry.metaState,
3132 keyEntry.repeatCount, keyEntry.downTime,
3133 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003134 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003135 }
3136
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003137 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003138 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003139
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003140 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003141 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003142
chaviw82357092020-01-28 13:13:06 -08003143 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003144 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003145 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3146 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003147 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003148 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3149 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003150 // Don't apply window scale here since we don't want scale to affect raw
3151 // coordinates. The scale will be sent back to the client and applied
3152 // later when requesting relative coordinates.
3153 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3154 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003155 }
3156 usingCoords = scaledCoords;
3157 }
3158 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003159 // We don't want the dispatch target to know.
3160 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003161 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003162 scaledCoords[i].clear();
3163 }
3164 usingCoords = scaledCoords;
3165 }
3166 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003167
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003168 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003169
3170 // Publish the motion event.
3171 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003172 .publishMotionEvent(dispatchEntry->seq,
3173 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003174 motionEntry.deviceId, motionEntry.source,
3175 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003176 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003177 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003178 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003179 motionEntry.edgeFlags, motionEntry.metaState,
3180 motionEntry.buttonState,
3181 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003182 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003183 motionEntry.xPrecision, motionEntry.yPrecision,
3184 motionEntry.xCursorPosition,
3185 motionEntry.yCursorPosition,
Evan Rosky09576692021-07-01 12:22:09 -07003186 dispatchEntry->displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -07003187 dispatchEntry->displaySize.x,
3188 dispatchEntry->displaySize.y,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003189 motionEntry.downTime, motionEntry.eventTime,
3190 motionEntry.pointerCount,
3191 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003192 break;
3193 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003194
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003195 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003196 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003197 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003198 focusEntry.id,
3199 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003200 mInTouchMode);
3201 break;
3202 }
3203
Prabir Pradhan99987712020-11-10 18:43:05 -08003204 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3205 const auto& captureEntry =
3206 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3207 status = connection->inputPublisher
3208 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhanac483a62021-08-06 14:01:18 +00003209 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003210 break;
3211 }
3212
arthurhungb89ccb02020-12-30 16:19:01 +08003213 case EventEntry::Type::DRAG: {
3214 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3215 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3216 dragEntry.id, dragEntry.x,
3217 dragEntry.y,
3218 dragEntry.isExiting);
3219 break;
3220 }
3221
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003222 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003223 case EventEntry::Type::DEVICE_RESET:
3224 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003225 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Chris Yef59a2f42020-10-16 12:55:26 -07003226 NamedEnum::string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003227 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003228 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003229 }
3230
3231 // Check the result.
3232 if (status) {
3233 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003234 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003235 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003236 "This is unexpected because the wait queue is empty, so the pipe "
3237 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003238 "event to it, status=%s(%d)",
3239 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3240 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003241 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3242 } else {
3243 // Pipe is full and we are waiting for the app to finish process some events
3244 // before sending more events to it.
3245#if DEBUG_DISPATCH_CYCLE
3246 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003247 "waiting for the application to catch up",
3248 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003249#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003250 }
3251 } else {
3252 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003253 "status=%s(%d)",
3254 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3255 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003256 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3257 }
3258 return;
3259 }
3260
3261 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003262 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3263 connection->outboundQueue.end(),
3264 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003265 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003266 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003267 if (connection->responsive) {
3268 mAnrTracker.insert(dispatchEntry->timeoutTime,
3269 connection->inputChannel->getConnectionToken());
3270 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003271 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003272 }
3273}
3274
chaviw09c8d2d2020-08-24 15:48:26 -07003275std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3276 size_t size;
3277 switch (event.type) {
3278 case VerifiedInputEvent::Type::KEY: {
3279 size = sizeof(VerifiedKeyEvent);
3280 break;
3281 }
3282 case VerifiedInputEvent::Type::MOTION: {
3283 size = sizeof(VerifiedMotionEvent);
3284 break;
3285 }
3286 }
3287 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3288 return mHmacKeyManager.sign(start, size);
3289}
3290
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003291const std::array<uint8_t, 32> InputDispatcher::getSignature(
3292 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3293 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3294 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3295 // Only sign events up and down events as the purely move events
3296 // are tied to their up/down counterparts so signing would be redundant.
3297 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3298 verifiedEvent.actionMasked = actionMasked;
3299 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003300 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003301 }
3302 return INVALID_HMAC;
3303}
3304
3305const std::array<uint8_t, 32> InputDispatcher::getSignature(
3306 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3307 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3308 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3309 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003310 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003311}
3312
Michael Wrightd02c5b62014-02-10 15:10:22 -08003313void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003314 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003315 bool handled, nsecs_t consumeTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003316#if DEBUG_DISPATCH_CYCLE
3317 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003318 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003319#endif
3320
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003321 if (connection->status == Connection::STATUS_BROKEN ||
3322 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003323 return;
3324 }
3325
3326 // Notify other system components and prepare to start the next dispatch cycle.
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003327 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled, consumeTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003328}
3329
3330void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003331 const sp<Connection>& connection,
3332 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003333#if DEBUG_DISPATCH_CYCLE
3334 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003335 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003336#endif
3337
3338 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003339 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003340 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003341 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003342 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003343
3344 // The connection appears to be unrecoverably broken.
3345 // Ignore already broken or zombie connections.
3346 if (connection->status == Connection::STATUS_NORMAL) {
3347 connection->status = Connection::STATUS_BROKEN;
3348
3349 if (notify) {
3350 // Notify other system components.
3351 onDispatchCycleBrokenLocked(currentTime, connection);
3352 }
3353 }
3354}
3355
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003356void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3357 while (!queue.empty()) {
3358 DispatchEntry* dispatchEntry = queue.front();
3359 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003360 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003361 }
3362}
3363
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003364void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003365 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003366 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003367 }
3368 delete dispatchEntry;
3369}
3370
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003371int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3372 std::scoped_lock _l(mLock);
3373 sp<Connection> connection = getConnectionLocked(connectionToken);
3374 if (connection == nullptr) {
3375 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3376 connectionToken.get(), events);
3377 return 0; // remove the callback
3378 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003379
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003380 bool notify;
3381 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3382 if (!(events & ALOOPER_EVENT_INPUT)) {
3383 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3384 "events=0x%x",
3385 connection->getInputChannelName().c_str(), events);
3386 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003387 }
3388
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003389 nsecs_t currentTime = now();
3390 bool gotOne = false;
3391 status_t status = OK;
3392 for (;;) {
3393 Result<InputPublisher::ConsumerResponse> result =
3394 connection->inputPublisher.receiveConsumerResponse();
3395 if (!result.ok()) {
3396 status = result.error().code();
3397 break;
3398 }
3399
3400 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3401 const InputPublisher::Finished& finish =
3402 std::get<InputPublisher::Finished>(*result);
3403 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3404 finish.consumeTime);
3405 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003406 if (shouldReportMetricsForConnection(*connection)) {
3407 const InputPublisher::Timeline& timeline =
3408 std::get<InputPublisher::Timeline>(*result);
3409 mLatencyTracker
3410 .trackGraphicsLatency(timeline.inputEventId,
3411 connection->inputChannel->getConnectionToken(),
3412 std::move(timeline.graphicsTimeline));
3413 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003414 }
3415 gotOne = true;
3416 }
3417 if (gotOne) {
3418 runCommandsLockedInterruptible();
3419 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003420 return 1;
3421 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003422 }
3423
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003424 notify = status != DEAD_OBJECT || !connection->monitor;
3425 if (notify) {
3426 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3427 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3428 status);
3429 }
3430 } else {
3431 // Monitor channels are never explicitly unregistered.
3432 // We do it automatically when the remote endpoint is closed so don't warn about them.
3433 const bool stillHaveWindowHandle =
3434 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3435 notify = !connection->monitor && stillHaveWindowHandle;
3436 if (notify) {
3437 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3438 connection->getInputChannelName().c_str(), events);
3439 }
3440 }
3441
3442 // Remove the channel.
3443 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3444 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003445}
3446
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003447void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003448 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003449 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003450 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003451 }
3452}
3453
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003454void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003455 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003456 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3457 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3458}
3459
3460void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3461 const CancelationOptions& options,
3462 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3463 for (const auto& it : monitorsByDisplay) {
3464 const std::vector<Monitor>& monitors = it.second;
3465 for (const Monitor& monitor : monitors) {
3466 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003467 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003468 }
3469}
3470
Michael Wrightd02c5b62014-02-10 15:10:22 -08003471void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003472 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003473 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003474 if (connection == nullptr) {
3475 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003476 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003477
3478 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003479}
3480
3481void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3482 const sp<Connection>& connection, const CancelationOptions& options) {
3483 if (connection->status == Connection::STATUS_BROKEN) {
3484 return;
3485 }
3486
3487 nsecs_t currentTime = now();
3488
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003489 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003490 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003491
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003492 if (cancelationEvents.empty()) {
3493 return;
3494 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003495#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003496 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3497 "with reality: %s, mode=%d.",
3498 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3499 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003500#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003501
3502 InputTarget target;
chaviw3277faf2021-05-19 16:45:23 -05003503 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003504 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3505 if (windowHandle != nullptr) {
chaviw3277faf2021-05-19 16:45:23 -05003506 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003507 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003508 target.globalScaleFactor = windowInfo->globalScaleFactor;
3509 }
3510 target.inputChannel = connection->inputChannel;
3511 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3512
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003513 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003514 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003515 switch (cancelationEventEntry->type) {
3516 case EventEntry::Type::KEY: {
3517 logOutboundKeyDetails("cancel - ",
3518 static_cast<const KeyEntry&>(*cancelationEventEntry));
3519 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003520 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003521 case EventEntry::Type::MOTION: {
3522 logOutboundMotionDetails("cancel - ",
3523 static_cast<const MotionEntry&>(*cancelationEventEntry));
3524 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003525 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003526 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08003527 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3528 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003529 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Chris Yef59a2f42020-10-16 12:55:26 -07003530 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003531 break;
3532 }
3533 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003534 case EventEntry::Type::DEVICE_RESET:
3535 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003536 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003537 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003538 break;
3539 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003540 }
3541
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003542 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3543 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003544 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003545
3546 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003547}
3548
Svet Ganov5d3bc372020-01-26 23:11:07 -08003549void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3550 const sp<Connection>& connection) {
3551 if (connection->status == Connection::STATUS_BROKEN) {
3552 return;
3553 }
3554
3555 nsecs_t currentTime = now();
3556
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003557 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003558 connection->inputState.synthesizePointerDownEvents(currentTime);
3559
3560 if (downEvents.empty()) {
3561 return;
3562 }
3563
3564#if DEBUG_OUTBOUND_EVENT_DETAILS
3565 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3566 connection->getInputChannelName().c_str(), downEvents.size());
3567#endif
3568
3569 InputTarget target;
chaviw3277faf2021-05-19 16:45:23 -05003570 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003571 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3572 if (windowHandle != nullptr) {
chaviw3277faf2021-05-19 16:45:23 -05003573 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003574 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003575 target.globalScaleFactor = windowInfo->globalScaleFactor;
3576 }
3577 target.inputChannel = connection->inputChannel;
3578 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3579
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003580 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003581 switch (downEventEntry->type) {
3582 case EventEntry::Type::MOTION: {
3583 logOutboundMotionDetails("down - ",
3584 static_cast<const MotionEntry&>(*downEventEntry));
3585 break;
3586 }
3587
3588 case EventEntry::Type::KEY:
3589 case EventEntry::Type::FOCUS:
3590 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003591 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003592 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003593 case EventEntry::Type::SENSOR:
3594 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003595 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003596 NamedEnum::string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003597 break;
3598 }
3599 }
3600
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003601 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3602 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003603 }
3604
3605 startDispatchCycleLocked(currentTime, connection);
3606}
3607
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003608std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3609 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003610 ALOG_ASSERT(pointerIds.value != 0);
3611
3612 uint32_t splitPointerIndexMap[MAX_POINTERS];
3613 PointerProperties splitPointerProperties[MAX_POINTERS];
3614 PointerCoords splitPointerCoords[MAX_POINTERS];
3615
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003616 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003617 uint32_t splitPointerCount = 0;
3618
3619 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003620 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003621 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003622 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003623 uint32_t pointerId = uint32_t(pointerProperties.id);
3624 if (pointerIds.hasBit(pointerId)) {
3625 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3626 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3627 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003628 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003629 splitPointerCount += 1;
3630 }
3631 }
3632
3633 if (splitPointerCount != pointerIds.count()) {
3634 // This is bad. We are missing some of the pointers that we expected to deliver.
3635 // Most likely this indicates that we received an ACTION_MOVE events that has
3636 // different pointer ids than we expected based on the previous ACTION_DOWN
3637 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3638 // in this way.
3639 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003640 "we expected there to be %d pointers. This probably means we received "
3641 "a broken sequence of pointer ids from the input device.",
3642 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003643 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003644 }
3645
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003646 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003647 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003648 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3649 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003650 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3651 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003652 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003653 uint32_t pointerId = uint32_t(pointerProperties.id);
3654 if (pointerIds.hasBit(pointerId)) {
3655 if (pointerIds.count() == 1) {
3656 // The first/last pointer went down/up.
3657 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003658 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003659 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3660 ? AMOTION_EVENT_ACTION_CANCEL
3661 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003662 } else {
3663 // A secondary pointer went down/up.
3664 uint32_t splitPointerIndex = 0;
3665 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3666 splitPointerIndex += 1;
3667 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003668 action = maskedAction |
3669 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003670 }
3671 } else {
3672 // An unrelated pointer changed.
3673 action = AMOTION_EVENT_ACTION_MOVE;
3674 }
3675 }
3676
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003677 int32_t newId = mIdGenerator.nextId();
3678 if (ATRACE_ENABLED()) {
3679 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3680 ") to MotionEvent(id=0x%" PRIx32 ").",
3681 originalMotionEntry.id, newId);
3682 ATRACE_NAME(message.c_str());
3683 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003684 std::unique_ptr<MotionEntry> splitMotionEntry =
3685 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3686 originalMotionEntry.deviceId, originalMotionEntry.source,
3687 originalMotionEntry.displayId,
3688 originalMotionEntry.policyFlags, action,
3689 originalMotionEntry.actionButton,
3690 originalMotionEntry.flags, originalMotionEntry.metaState,
3691 originalMotionEntry.buttonState,
3692 originalMotionEntry.classification,
3693 originalMotionEntry.edgeFlags,
3694 originalMotionEntry.xPrecision,
3695 originalMotionEntry.yPrecision,
3696 originalMotionEntry.xCursorPosition,
3697 originalMotionEntry.yCursorPosition,
3698 originalMotionEntry.downTime, splitPointerCount,
3699 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003700
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003701 if (originalMotionEntry.injectionState) {
3702 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003703 splitMotionEntry->injectionState->refCount += 1;
3704 }
3705
3706 return splitMotionEntry;
3707}
3708
3709void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3710#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003711 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003712#endif
3713
3714 bool needWake;
3715 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003716 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003717
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003718 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3719 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3720 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003721 } // release lock
3722
3723 if (needWake) {
3724 mLooper->wake();
3725 }
3726}
3727
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003728/**
3729 * If one of the meta shortcuts is detected, process them here:
3730 * Meta + Backspace -> generate BACK
3731 * Meta + Enter -> generate HOME
3732 * This will potentially overwrite keyCode and metaState.
3733 */
3734void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003735 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003736 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3737 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3738 if (keyCode == AKEYCODE_DEL) {
3739 newKeyCode = AKEYCODE_BACK;
3740 } else if (keyCode == AKEYCODE_ENTER) {
3741 newKeyCode = AKEYCODE_HOME;
3742 }
3743 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003744 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003745 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003746 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003747 keyCode = newKeyCode;
3748 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3749 }
3750 } else if (action == AKEY_EVENT_ACTION_UP) {
3751 // In order to maintain a consistent stream of up and down events, check to see if the key
3752 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3753 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003754 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003755 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003756 auto replacementIt = mReplacedKeys.find(replacement);
3757 if (replacementIt != mReplacedKeys.end()) {
3758 keyCode = replacementIt->second;
3759 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003760 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3761 }
3762 }
3763}
3764
Michael Wrightd02c5b62014-02-10 15:10:22 -08003765void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3766#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003767 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3768 "policyFlags=0x%x, action=0x%x, "
3769 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3770 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3771 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3772 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003773#endif
3774 if (!validateKeyEvent(args->action)) {
3775 return;
3776 }
3777
3778 uint32_t policyFlags = args->policyFlags;
3779 int32_t flags = args->flags;
3780 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003781 // InputDispatcher tracks and generates key repeats on behalf of
3782 // whatever notifies it, so repeatCount should always be set to 0
3783 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003784 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3785 policyFlags |= POLICY_FLAG_VIRTUAL;
3786 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3787 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003788 if (policyFlags & POLICY_FLAG_FUNCTION) {
3789 metaState |= AMETA_FUNCTION_ON;
3790 }
3791
3792 policyFlags |= POLICY_FLAG_TRUSTED;
3793
Michael Wright78f24442014-08-06 15:55:28 -07003794 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003795 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003796
Michael Wrightd02c5b62014-02-10 15:10:22 -08003797 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003798 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003799 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3800 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003801
Michael Wright2b3c3302018-03-02 17:19:13 +00003802 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003803 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003804 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3805 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003806 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003807 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003808
Michael Wrightd02c5b62014-02-10 15:10:22 -08003809 bool needWake;
3810 { // acquire lock
3811 mLock.lock();
3812
3813 if (shouldSendKeyToInputFilterLocked(args)) {
3814 mLock.unlock();
3815
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003816 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003817 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3818 return; // event was consumed by the filter
3819 }
3820
3821 mLock.lock();
3822 }
3823
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003824 std::unique_ptr<KeyEntry> newEntry =
3825 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3826 args->displayId, policyFlags, args->action, flags,
3827 keyCode, args->scanCode, metaState, repeatCount,
3828 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003829
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003830 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003831 mLock.unlock();
3832 } // release lock
3833
3834 if (needWake) {
3835 mLooper->wake();
3836 }
3837}
3838
3839bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3840 return mInputFilterEnabled;
3841}
3842
3843void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3844#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003845 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3846 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003847 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3848 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003849 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003850 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3851 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3852 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3853 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003854 for (uint32_t i = 0; i < args->pointerCount; i++) {
3855 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003856 "x=%f, y=%f, pressure=%f, size=%f, "
3857 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3858 "orientation=%f",
3859 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3860 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3861 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3862 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3863 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3864 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3865 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3866 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3867 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3868 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003869 }
3870#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003871 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3872 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003873 return;
3874 }
3875
3876 uint32_t policyFlags = args->policyFlags;
3877 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003878
3879 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003880 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003881 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3882 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003883 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003884 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003885
3886 bool needWake;
3887 { // acquire lock
3888 mLock.lock();
3889
3890 if (shouldSendMotionToInputFilterLocked(args)) {
3891 mLock.unlock();
3892
3893 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003894 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003895 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3896 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003897 args->metaState, args->buttonState, args->classification, transform,
3898 args->xPrecision, args->yPrecision, args->xCursorPosition,
Evan Rosky09576692021-07-01 12:22:09 -07003899 args->yCursorPosition, ui::Transform::ROT_0, INVALID_DISPLAY_SIZE,
3900 INVALID_DISPLAY_SIZE, args->downTime, args->eventTime,
3901 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003902
3903 policyFlags |= POLICY_FLAG_FILTERED;
3904 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3905 return; // event was consumed by the filter
3906 }
3907
3908 mLock.lock();
3909 }
3910
3911 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003912 std::unique_ptr<MotionEntry> newEntry =
3913 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3914 args->source, args->displayId, policyFlags,
3915 args->action, args->actionButton, args->flags,
3916 args->metaState, args->buttonState,
3917 args->classification, args->edgeFlags,
3918 args->xPrecision, args->yPrecision,
3919 args->xCursorPosition, args->yCursorPosition,
3920 args->downTime, args->pointerCount,
3921 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003922
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003923 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003924 mLock.unlock();
3925 } // release lock
3926
3927 if (needWake) {
3928 mLooper->wake();
3929 }
3930}
3931
Chris Yef59a2f42020-10-16 12:55:26 -07003932void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
3933#if DEBUG_INBOUND_EVENT_DETAILS
3934 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3935 " sensorType=%s",
3936 args->id, args->eventTime, args->deviceId, args->source,
3937 NamedEnum::string(args->sensorType).c_str());
3938#endif
3939
3940 bool needWake;
3941 { // acquire lock
3942 mLock.lock();
3943
3944 // Just enqueue a new sensor event.
3945 std::unique_ptr<SensorEntry> newEntry =
3946 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
3947 args->source, 0 /* policyFlags*/, args->hwTimestamp,
3948 args->sensorType, args->accuracy,
3949 args->accuracyChanged, args->values);
3950
3951 needWake = enqueueInboundEventLocked(std::move(newEntry));
3952 mLock.unlock();
3953 } // release lock
3954
3955 if (needWake) {
3956 mLooper->wake();
3957 }
3958}
3959
Chris Yefb552902021-02-03 17:18:37 -08003960void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
3961#if DEBUG_INBOUND_EVENT_DETAILS
3962 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
3963 args->deviceId, args->isOn);
3964#endif
3965 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
3966}
3967
Michael Wrightd02c5b62014-02-10 15:10:22 -08003968bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003969 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003970}
3971
3972void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3973#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003974 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003975 "switchMask=0x%08x",
3976 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003977#endif
3978
3979 uint32_t policyFlags = args->policyFlags;
3980 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003981 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003982}
3983
3984void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3985#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003986 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3987 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003988#endif
3989
3990 bool needWake;
3991 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003992 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003993
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003994 std::unique_ptr<DeviceResetEntry> newEntry =
3995 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3996 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003997 } // release lock
3998
3999 if (needWake) {
4000 mLooper->wake();
4001 }
4002}
4003
Prabir Pradhan7e186182020-11-10 13:56:45 -08004004void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
4005#if DEBUG_INBOUND_EVENT_DETAILS
4006 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
Prabir Pradhanac483a62021-08-06 14:01:18 +00004007 args->request.enable ? "true" : "false");
Prabir Pradhan7e186182020-11-10 13:56:45 -08004008#endif
4009
Prabir Pradhan99987712020-11-10 18:43:05 -08004010 bool needWake;
4011 { // acquire lock
4012 std::scoped_lock _l(mLock);
4013 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
Prabir Pradhanac483a62021-08-06 14:01:18 +00004014 args->request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004015 needWake = enqueueInboundEventLocked(std::move(entry));
4016 } // release lock
4017
4018 if (needWake) {
4019 mLooper->wake();
4020 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004021}
4022
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004023InputEventInjectionResult InputDispatcher::injectInputEvent(
4024 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4025 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004026#if DEBUG_INBOUND_EVENT_DETAILS
4027 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004028 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4029 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004030#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004031 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004032
4033 policyFlags |= POLICY_FLAG_INJECTED;
4034 if (hasInjectionPermission(injectorPid, injectorUid)) {
4035 policyFlags |= POLICY_FLAG_TRUSTED;
4036 }
4037
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004038 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004039 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4040 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4041 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4042 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4043 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004044 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004045 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004046 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004047 }
4048
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004049 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004050 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004051 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004052 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4053 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004054 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004055 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004056 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004057
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004058 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004059 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4060 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4061 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004062 int32_t keyCode = incomingKey.getKeyCode();
4063 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004064 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004065 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004066 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004067 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004068 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4069 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4070 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004071
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004072 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4073 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004074 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004075
4076 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4077 android::base::Timer t;
4078 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4079 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4080 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4081 std::to_string(t.duration().count()).c_str());
4082 }
4083 }
4084
4085 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004086 std::unique_ptr<KeyEntry> injectedEntry =
4087 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004088 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004089 incomingKey.getDisplayId(), policyFlags, action,
4090 flags, keyCode, incomingKey.getScanCode(), metaState,
4091 incomingKey.getRepeatCount(),
4092 incomingKey.getDownTime());
4093 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004094 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004095 }
4096
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004097 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004098 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
4099 int32_t action = motionEvent.getAction();
4100 size_t pointerCount = motionEvent.getPointerCount();
4101 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
4102 int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004103 int32_t flags = motionEvent.getFlags();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004104 int32_t displayId = motionEvent.getDisplayId();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004105 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004106 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004107 }
4108
4109 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004110 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004111 android::base::Timer t;
4112 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4113 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4114 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4115 std::to_string(t.duration().count()).c_str());
4116 }
4117 }
4118
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004119 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4120 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4121 }
4122
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004123 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004124 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4125 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004126 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004127 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4128 resolvedDeviceId, motionEvent.getSource(),
4129 motionEvent.getDisplayId(), policyFlags, action,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004130 actionButton, flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004131 motionEvent.getButtonState(),
4132 motionEvent.getClassification(),
4133 motionEvent.getEdgeFlags(),
4134 motionEvent.getXPrecision(),
4135 motionEvent.getYPrecision(),
4136 motionEvent.getRawXCursorPosition(),
4137 motionEvent.getRawYCursorPosition(),
4138 motionEvent.getDownTime(), uint32_t(pointerCount),
4139 pointerProperties, samplePointerCoords,
4140 motionEvent.getXOffset(),
4141 motionEvent.getYOffset());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004142 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004143 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004144 sampleEventTimes += 1;
4145 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004146 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004147 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4148 resolvedDeviceId, motionEvent.getSource(),
4149 motionEvent.getDisplayId(), policyFlags,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004150 action, actionButton, flags,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004151 motionEvent.getMetaState(),
4152 motionEvent.getButtonState(),
4153 motionEvent.getClassification(),
4154 motionEvent.getEdgeFlags(),
4155 motionEvent.getXPrecision(),
4156 motionEvent.getYPrecision(),
4157 motionEvent.getRawXCursorPosition(),
4158 motionEvent.getRawYCursorPosition(),
4159 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004160 uint32_t(pointerCount), pointerProperties,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004161 samplePointerCoords, motionEvent.getXOffset(),
4162 motionEvent.getYOffset());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004163 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004164 }
4165 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004166 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004167
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004168 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004169 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004170 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004171 }
4172
4173 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004174 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004175 injectionState->injectionIsAsync = true;
4176 }
4177
4178 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004179 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004180
4181 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004182 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004183 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004184 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004185 }
4186
4187 mLock.unlock();
4188
4189 if (needWake) {
4190 mLooper->wake();
4191 }
4192
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004193 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004194 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004195 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004196
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004197 if (syncMode == InputEventInjectionSync::NONE) {
4198 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004199 } else {
4200 for (;;) {
4201 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004202 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004203 break;
4204 }
4205
4206 nsecs_t remainingTimeout = endTime - now();
4207 if (remainingTimeout <= 0) {
4208#if DEBUG_INJECTION
4209 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004210 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004211#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004212 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004213 break;
4214 }
4215
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004216 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004217 }
4218
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004219 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4220 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004221 while (injectionState->pendingForegroundDispatches != 0) {
4222#if DEBUG_INJECTION
4223 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004224 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004225#endif
4226 nsecs_t remainingTimeout = endTime - now();
4227 if (remainingTimeout <= 0) {
4228#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004229 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4230 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004231#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004232 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004233 break;
4234 }
4235
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004236 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004237 }
4238 }
4239 }
4240
4241 injectionState->release();
4242 } // release lock
4243
4244#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004245 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004246 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004247#endif
4248
4249 return injectionResult;
4250}
4251
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004252std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004253 std::array<uint8_t, 32> calculatedHmac;
4254 std::unique_ptr<VerifiedInputEvent> result;
4255 switch (event.getType()) {
4256 case AINPUT_EVENT_TYPE_KEY: {
4257 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4258 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4259 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004260 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004261 break;
4262 }
4263 case AINPUT_EVENT_TYPE_MOTION: {
4264 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4265 VerifiedMotionEvent verifiedMotionEvent =
4266 verifiedMotionEventFromMotionEvent(motionEvent);
4267 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004268 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004269 break;
4270 }
4271 default: {
4272 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4273 return nullptr;
4274 }
4275 }
4276 if (calculatedHmac == INVALID_HMAC) {
4277 return nullptr;
4278 }
4279 if (calculatedHmac != event.getHmac()) {
4280 return nullptr;
4281 }
4282 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004283}
4284
Michael Wrightd02c5b62014-02-10 15:10:22 -08004285bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004286 return injectorUid == 0 ||
4287 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004288}
4289
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004290void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004291 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004292 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004293 if (injectionState) {
4294#if DEBUG_INJECTION
4295 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004296 "injectorPid=%d, injectorUid=%d",
4297 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004298#endif
4299
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004300 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004301 // Log the outcome since the injector did not wait for the injection result.
4302 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004303 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004304 ALOGV("Asynchronous input event injection succeeded.");
4305 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004306 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004307 ALOGW("Asynchronous input event injection failed.");
4308 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004309 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004310 ALOGW("Asynchronous input event injection permission denied.");
4311 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004312 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004313 ALOGW("Asynchronous input event injection timed out.");
4314 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004315 case InputEventInjectionResult::PENDING:
4316 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4317 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004318 }
4319 }
4320
4321 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004322 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004323 }
4324}
4325
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004326void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4327 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004328 if (injectionState) {
4329 injectionState->pendingForegroundDispatches += 1;
4330 }
4331}
4332
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004333void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4334 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004335 if (injectionState) {
4336 injectionState->pendingForegroundDispatches -= 1;
4337
4338 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004339 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004340 }
4341 }
4342}
4343
chaviw3277faf2021-05-19 16:45:23 -05004344const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004345 int32_t displayId) const {
chaviw3277faf2021-05-19 16:45:23 -05004346 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004347 auto it = mWindowHandlesByDisplay.find(displayId);
4348 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004349}
4350
chaviw3277faf2021-05-19 16:45:23 -05004351sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004352 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004353 if (windowHandleToken == nullptr) {
4354 return nullptr;
4355 }
4356
Arthur Hungb92218b2018-08-14 12:00:21 +08004357 for (auto& it : mWindowHandlesByDisplay) {
chaviw3277faf2021-05-19 16:45:23 -05004358 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4359 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004360 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004361 return windowHandle;
4362 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004363 }
4364 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004365 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004366}
4367
chaviw3277faf2021-05-19 16:45:23 -05004368sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4369 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004370 if (windowHandleToken == nullptr) {
4371 return nullptr;
4372 }
4373
chaviw3277faf2021-05-19 16:45:23 -05004374 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004375 if (windowHandle->getToken() == windowHandleToken) {
4376 return windowHandle;
4377 }
4378 }
4379 return nullptr;
4380}
4381
chaviw3277faf2021-05-19 16:45:23 -05004382sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4383 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004384 for (auto& it : mWindowHandlesByDisplay) {
chaviw3277faf2021-05-19 16:45:23 -05004385 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4386 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004387 if (handle->getId() == windowHandle->getId() &&
4388 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004389 if (windowHandle->getInfo()->displayId != it.first) {
4390 ALOGE("Found window %s in display %" PRId32
4391 ", but it should belong to display %" PRId32,
4392 windowHandle->getName().c_str(), it.first,
4393 windowHandle->getInfo()->displayId);
4394 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004395 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004396 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004397 }
4398 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004399 return nullptr;
4400}
4401
chaviw3277faf2021-05-19 16:45:23 -05004402sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004403 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4404 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004405}
4406
chaviw3277faf2021-05-19 16:45:23 -05004407bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004408 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4409 const bool noInputChannel =
chaviw3277faf2021-05-19 16:45:23 -05004410 windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004411 if (connection != nullptr && noInputChannel) {
4412 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4413 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4414 return false;
4415 }
4416
4417 if (connection == nullptr) {
4418 if (!noInputChannel) {
4419 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4420 }
4421 return false;
4422 }
4423 if (!connection->responsive) {
4424 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4425 return false;
4426 }
4427 return true;
4428}
4429
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004430std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4431 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004432 auto connectionIt = mConnectionsByToken.find(token);
4433 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004434 return nullptr;
4435 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004436 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004437}
4438
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004439void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw3277faf2021-05-19 16:45:23 -05004440 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4441 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004442 // Remove all handles on a display if there are no windows left.
4443 mWindowHandlesByDisplay.erase(displayId);
4444 return;
4445 }
4446
4447 // Since we compare the pointer of input window handles across window updates, we need
4448 // to make sure the handle object for the same window stays unchanged across updates.
chaviw3277faf2021-05-19 16:45:23 -05004449 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4450 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4451 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004452 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004453 }
4454
chaviw3277faf2021-05-19 16:45:23 -05004455 std::vector<sp<WindowInfoHandle>> newHandles;
4456 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw3277faf2021-05-19 16:45:23 -05004457 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004458 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4459 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4460 const bool noInputChannel =
chaviw3277faf2021-05-19 16:45:23 -05004461 info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
4462 const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
4463 !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004464 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004465 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004466 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004467 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004468 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004469 }
4470
4471 if (info->displayId != displayId) {
4472 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4473 handle->getName().c_str(), displayId, info->displayId);
4474 continue;
4475 }
4476
Robert Carredd13602020-04-13 17:24:34 -07004477 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4478 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw3277faf2021-05-19 16:45:23 -05004479 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004480 oldHandle->updateFrom(handle);
4481 newHandles.push_back(oldHandle);
4482 } else {
4483 newHandles.push_back(handle);
4484 }
4485 }
4486
4487 // Insert or replace
4488 mWindowHandlesByDisplay[displayId] = newHandles;
4489}
4490
Arthur Hung72d8dc32020-03-28 00:48:39 +00004491void InputDispatcher::setInputWindows(
chaviw3277faf2021-05-19 16:45:23 -05004492 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004493 { // acquire lock
4494 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004495 for (const auto& [displayId, handles] : handlesPerDisplay) {
4496 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004497 }
4498 }
4499 // Wake up poll loop since it may need to make new input dispatching choices.
4500 mLooper->wake();
4501}
4502
Arthur Hungb92218b2018-08-14 12:00:21 +08004503/**
4504 * Called from InputManagerService, update window handle list by displayId that can receive input.
4505 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4506 * If set an empty list, remove all handles from the specific display.
4507 * For focused handle, check if need to change and send a cancel event to previous one.
4508 * For removed handle, check if need to send a cancel event if already in touch.
4509 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004510void InputDispatcher::setInputWindowsLocked(
chaviw3277faf2021-05-19 16:45:23 -05004511 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004512 if (DEBUG_FOCUS) {
4513 std::string windowList;
chaviw3277faf2021-05-19 16:45:23 -05004514 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004515 windowList += iwh->getName() + " ";
4516 }
4517 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4518 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004519
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004520 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
chaviw3277faf2021-05-19 16:45:23 -05004521 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004522 const bool noInputWindow =
chaviw3277faf2021-05-19 16:45:23 -05004523 window->getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004524 if (noInputWindow && window->getToken() != nullptr) {
4525 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4526 window->getName().c_str());
4527 window->releaseChannel();
4528 }
4529 }
4530
Arthur Hung72d8dc32020-03-28 00:48:39 +00004531 // Copy old handles for release if they are no longer present.
chaviw3277faf2021-05-19 16:45:23 -05004532 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004533
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004534 // Save the old windows' orientation by ID before it gets updated.
4535 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw3277faf2021-05-19 16:45:23 -05004536 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004537 oldWindowOrientations.emplace(handle->getId(),
4538 handle->getInfo()->transform.getOrientation());
4539 }
4540
chaviw3277faf2021-05-19 16:45:23 -05004541 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004542
chaviw3277faf2021-05-19 16:45:23 -05004543 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004544 if (mLastHoverWindowHandle &&
4545 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4546 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004547 mLastHoverWindowHandle = nullptr;
4548 }
4549
Vishnu Nairc519ff72021-01-21 08:23:08 -08004550 std::optional<FocusResolver::FocusChanges> changes =
4551 mFocusResolver.setInputWindows(displayId, windowHandles);
4552 if (changes) {
4553 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004554 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004555
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004556 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4557 mTouchStatesByDisplay.find(displayId);
4558 if (stateIt != mTouchStatesByDisplay.end()) {
4559 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004560 for (size_t i = 0; i < state.windows.size();) {
4561 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004562 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004563 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004564 ALOGD("Touched window was removed: %s in display %" PRId32,
4565 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004566 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004567 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004568 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4569 if (touchedInputChannel != nullptr) {
4570 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4571 "touched window was removed");
4572 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004573 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004574 state.windows.erase(state.windows.begin() + i);
4575 } else {
4576 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004577 }
4578 }
arthurhungb89ccb02020-12-30 16:19:01 +08004579
arthurhung6d4bed92021-03-17 11:59:33 +08004580 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004581 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004582 if (mDragState &&
4583 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004584 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004585 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004586 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004587 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004588
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004589 if (isPerWindowInputRotationEnabled()) {
4590 // Determine if the orientation of any of the input windows have changed, and cancel all
4591 // pointer events if necessary.
chaviw3277faf2021-05-19 16:45:23 -05004592 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4593 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004594 if (newWindowHandle != nullptr &&
4595 newWindowHandle->getInfo()->transform.getOrientation() !=
4596 oldWindowOrientations[oldWindowHandle->getId()]) {
4597 std::shared_ptr<InputChannel> inputChannel =
4598 getInputChannelLocked(newWindowHandle->getToken());
4599 if (inputChannel != nullptr) {
4600 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4601 "touched window's orientation changed");
4602 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4603 }
4604 }
4605 }
4606 }
4607
Arthur Hung72d8dc32020-03-28 00:48:39 +00004608 // Release information for windows that are no longer present.
4609 // This ensures that unused input channels are released promptly.
4610 // Otherwise, they might stick around until the window handle is destroyed
4611 // which might not happen until the next GC.
chaviw3277faf2021-05-19 16:45:23 -05004612 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004613 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004614 if (DEBUG_FOCUS) {
4615 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004616 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004617 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004618 // To avoid making too many calls into the compat framework, only
4619 // check for window flags when windows are going away.
4620 // TODO(b/157929241) : delete this. This is only needed temporarily
4621 // in order to gather some data about the flag usage
chaviw3277faf2021-05-19 16:45:23 -05004622 if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004623 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4624 oldWindowHandle->getName().c_str());
4625 if (mCompatService != nullptr) {
4626 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4627 oldWindowHandle->getInfo()->ownerUid);
4628 }
4629 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004630 }
chaviw291d88a2019-02-14 10:33:58 -08004631 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004632}
4633
4634void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004635 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004636 if (DEBUG_FOCUS) {
4637 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4638 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4639 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004640 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004641 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004642 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004643 } // release lock
4644
4645 // Wake up poll loop since it may need to make new input dispatching choices.
4646 mLooper->wake();
4647}
4648
Vishnu Nair599f1412021-06-21 10:39:58 -07004649void InputDispatcher::setFocusedApplicationLocked(
4650 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4651 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4652 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4653
4654 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4655 return; // This application is already focused. No need to wake up or change anything.
4656 }
4657
4658 // Set the new application handle.
4659 if (inputApplicationHandle != nullptr) {
4660 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4661 } else {
4662 mFocusedApplicationHandlesByDisplay.erase(displayId);
4663 }
4664
4665 // No matter what the old focused application was, stop waiting on it because it is
4666 // no longer focused.
4667 resetNoFocusedWindowTimeoutLocked();
4668}
4669
Tiger Huang721e26f2018-07-24 22:26:19 +08004670/**
4671 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4672 * the display not specified.
4673 *
4674 * We track any unreleased events for each window. If a window loses the ability to receive the
4675 * released event, we will send a cancel event to it. So when the focused display is changed, we
4676 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4677 * display. The display-specified events won't be affected.
4678 */
4679void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004680 if (DEBUG_FOCUS) {
4681 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4682 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004683 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004684 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004685
4686 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004687 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004688 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004689 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004690 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004691 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004692 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004693 CancelationOptions
4694 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4695 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004696 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004697 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4698 }
4699 }
4700 mFocusedDisplayId = displayId;
4701
Chris Ye3c2d6f52020-08-09 10:39:48 -07004702 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004703 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004704 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004705
Vishnu Nairad321cd2020-08-20 16:40:21 -07004706 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004707 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004708 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004709 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004710 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004711 }
4712 }
4713 }
4714
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004715 if (DEBUG_FOCUS) {
4716 logDispatchStateLocked();
4717 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004718 } // release lock
4719
4720 // Wake up poll loop since it may need to make new input dispatching choices.
4721 mLooper->wake();
4722}
4723
Michael Wrightd02c5b62014-02-10 15:10:22 -08004724void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004725 if (DEBUG_FOCUS) {
4726 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4727 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004728
4729 bool changed;
4730 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004731 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004732
4733 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4734 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004735 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004736 }
4737
4738 if (mDispatchEnabled && !enabled) {
4739 resetAndDropEverythingLocked("dispatcher is being disabled");
4740 }
4741
4742 mDispatchEnabled = enabled;
4743 mDispatchFrozen = frozen;
4744 changed = true;
4745 } else {
4746 changed = false;
4747 }
4748
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004749 if (DEBUG_FOCUS) {
4750 logDispatchStateLocked();
4751 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004752 } // release lock
4753
4754 if (changed) {
4755 // Wake up poll loop since it may need to make new input dispatching choices.
4756 mLooper->wake();
4757 }
4758}
4759
4760void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004761 if (DEBUG_FOCUS) {
4762 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4763 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004764
4765 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004766 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004767
4768 if (mInputFilterEnabled == enabled) {
4769 return;
4770 }
4771
4772 mInputFilterEnabled = enabled;
4773 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4774 } // release lock
4775
4776 // Wake up poll loop since there might be work to do to drop everything.
4777 mLooper->wake();
4778}
4779
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004780void InputDispatcher::setInTouchMode(bool inTouchMode) {
4781 std::scoped_lock lock(mLock);
4782 mInTouchMode = inTouchMode;
4783}
4784
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004785void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4786 if (opacity < 0 || opacity > 1) {
4787 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4788 return;
4789 }
4790
4791 std::scoped_lock lock(mLock);
4792 mMaximumObscuringOpacityForTouch = opacity;
4793}
4794
4795void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4796 std::scoped_lock lock(mLock);
4797 mBlockUntrustedTouchesMode = mode;
4798}
4799
arthurhungb89ccb02020-12-30 16:19:01 +08004800bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4801 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004802 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004803 if (DEBUG_FOCUS) {
4804 ALOGD("Trivial transfer to same window.");
4805 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004806 return true;
4807 }
4808
Michael Wrightd02c5b62014-02-10 15:10:22 -08004809 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004810 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004811
chaviw3277faf2021-05-19 16:45:23 -05004812 sp<WindowInfoHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4813 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004814 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004815 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004816 return false;
4817 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004818 if (DEBUG_FOCUS) {
4819 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4820 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4821 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004822 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004823 if (DEBUG_FOCUS) {
4824 ALOGD("Cannot transfer focus because windows are on different displays.");
4825 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004826 return false;
4827 }
4828
4829 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004830 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4831 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004832 for (size_t i = 0; i < state.windows.size(); i++) {
4833 const TouchedWindow& touchedWindow = state.windows[i];
4834 if (touchedWindow.windowHandle == fromWindowHandle) {
4835 int32_t oldTargetFlags = touchedWindow.targetFlags;
4836 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004837
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004838 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004839
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004840 int32_t newTargetFlags = oldTargetFlags &
4841 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4842 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004843 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004844
arthurhungb89ccb02020-12-30 16:19:01 +08004845 // Store the dragging window.
4846 if (isDragDrop) {
arthurhung6d4bed92021-03-17 11:59:33 +08004847 mDragState = std::make_unique<DragState>(toWindowHandle);
arthurhungb89ccb02020-12-30 16:19:01 +08004848 }
4849
Jeff Brownf086ddb2014-02-11 14:28:48 -08004850 found = true;
4851 goto Found;
4852 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004853 }
4854 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004855 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004856
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004857 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004858 if (DEBUG_FOCUS) {
4859 ALOGD("Focus transfer failed because from window did not have focus.");
4860 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004861 return false;
4862 }
4863
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004864 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4865 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004866 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004867 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004868 CancelationOptions
4869 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4870 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004871 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004872 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004873 }
4874
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004875 if (DEBUG_FOCUS) {
4876 logDispatchStateLocked();
4877 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004878 } // release lock
4879
4880 // Wake up poll loop since it may need to make new input dispatching choices.
4881 mLooper->wake();
4882 return true;
4883}
4884
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00004885// Binder call
4886bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
4887 sp<IBinder> fromToken;
4888 { // acquire lock
4889 std::scoped_lock _l(mLock);
4890
chaviw3277faf2021-05-19 16:45:23 -05004891 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00004892 if (toWindowHandle == nullptr) {
4893 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
4894 return false;
4895 }
4896
4897 const int32_t displayId = toWindowHandle->getInfo()->displayId;
4898
4899 auto touchStateIt = mTouchStatesByDisplay.find(displayId);
4900 if (touchStateIt == mTouchStatesByDisplay.end()) {
4901 ALOGD("Could not transfer touch because the display %" PRId32 " is not being touched",
4902 displayId);
4903 return false;
4904 }
4905
4906 TouchState& state = touchStateIt->second;
4907 if (state.windows.size() != 1) {
4908 ALOGW("Cannot transfer touch state because there are %zu windows being touched",
4909 state.windows.size());
4910 return false;
4911 }
4912 const TouchedWindow& touchedWindow = state.windows[0];
4913 fromToken = touchedWindow.windowHandle->getToken();
4914 } // release lock
4915
4916 return transferTouchFocus(fromToken, destChannelToken);
4917}
4918
Michael Wrightd02c5b62014-02-10 15:10:22 -08004919void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004920 if (DEBUG_FOCUS) {
4921 ALOGD("Resetting and dropping all events (%s).", reason);
4922 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004923
4924 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4925 synthesizeCancelationEventsForAllConnectionsLocked(options);
4926
4927 resetKeyRepeatLocked();
4928 releasePendingEventLocked();
4929 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004930 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004931
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004932 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004933 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004934 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004935 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004936}
4937
4938void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004939 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004940 dumpDispatchStateLocked(dump);
4941
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004942 std::istringstream stream(dump);
4943 std::string line;
4944
4945 while (std::getline(stream, line, '\n')) {
4946 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004947 }
4948}
4949
Prabir Pradhan99987712020-11-10 18:43:05 -08004950std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4951 std::string dump;
4952
Prabir Pradhanac483a62021-08-06 14:01:18 +00004953 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
4954 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08004955
4956 std::string windowName = "None";
4957 if (mWindowTokenWithPointerCapture) {
chaviw3277faf2021-05-19 16:45:23 -05004958 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08004959 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4960 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4961 : "token has capture without window";
4962 }
Prabir Pradhanac483a62021-08-06 14:01:18 +00004963 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08004964
4965 return dump;
4966}
4967
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004968void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004969 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4970 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4971 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004972 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004973
Tiger Huang721e26f2018-07-24 22:26:19 +08004974 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4975 dump += StringPrintf(INDENT "FocusedApplications:\n");
4976 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4977 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004978 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004979 const std::chrono::duration timeout =
4980 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004981 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004982 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004983 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004984 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004985 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004986 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004987 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004988
Vishnu Nairc519ff72021-01-21 08:23:08 -08004989 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08004990 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004991
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004992 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004993 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004994 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4995 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004996 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004997 state.displayId, toString(state.down), toString(state.split),
4998 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004999 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005000 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005001 for (size_t i = 0; i < state.windows.size(); i++) {
5002 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005003 dump += StringPrintf(INDENT4
5004 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
5005 i, touchedWindow.windowHandle->getName().c_str(),
5006 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005007 }
5008 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005009 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005010 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005011 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005012 dump += INDENT3 "Portal windows:\n";
5013 for (size_t i = 0; i < state.portalWindows.size(); i++) {
chaviw3277faf2021-05-19 16:45:23 -05005014 const sp<WindowInfoHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005015 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
5016 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005017 }
5018 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005019 }
5020 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005021 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005022 }
5023
arthurhung6d4bed92021-03-17 11:59:33 +08005024 if (mDragState) {
5025 dump += StringPrintf(INDENT "DragState:\n");
5026 mDragState->dump(dump, INDENT2);
5027 }
5028
Arthur Hungb92218b2018-08-14 12:00:21 +08005029 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005030 for (auto& it : mWindowHandlesByDisplay) {
chaviw3277faf2021-05-19 16:45:23 -05005031 const std::vector<sp<WindowInfoHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08005032 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005033 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005034 dump += INDENT2 "Windows:\n";
5035 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw3277faf2021-05-19 16:45:23 -05005036 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5037 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005038
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005039 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07005040 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005041 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005042 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005043 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005044 "applicationInfo.name=%s, "
5045 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005046 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005047 i, windowInfo->name.c_str(), windowInfo->id,
5048 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005049 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07005050 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005051 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005052 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01005053 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005054 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01005055 windowInfo->frameLeft, windowInfo->frameTop,
5056 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005057 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005058 windowInfo->applicationInfo.name.c_str(),
5059 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005060 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01005061 dump += StringPrintf(", inputFeatures=%s",
5062 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005063 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005064 "ms, trustedOverlay=%s, hasToken=%s, "
Prabir Pradhan817f6062021-08-16 12:15:11 -07005065 "touchOcclusionMode=%s, displayOrientation=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005066 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005067 millis(windowInfo->dispatchingTimeout),
5068 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005069 toString(windowInfo->token != nullptr),
Prabir Pradhan817f6062021-08-16 12:15:11 -07005070 toString(windowInfo->touchOcclusionMode).c_str(),
5071 windowInfo->displayOrientation);
chaviw85b44202020-07-24 11:46:21 -07005072 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005073 }
5074 } else {
5075 dump += INDENT2 "Windows: <none>\n";
5076 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005077 }
5078 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005079 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005080 }
5081
Michael Wright3dd60e22019-03-27 22:06:44 +00005082 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005083 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005084 const std::vector<Monitor>& monitors = it.second;
5085 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
5086 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005087 }
5088 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005089 const std::vector<Monitor>& monitors = it.second;
5090 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
5091 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005092 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005093 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00005094 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005095 }
5096
5097 nsecs_t currentTime = now();
5098
5099 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005100 if (!mRecentQueue.empty()) {
5101 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005102 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005103 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005104 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005105 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005106 }
5107 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005108 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005109 }
5110
5111 // Dump event currently being dispatched.
5112 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005113 dump += INDENT "PendingEvent:\n";
5114 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005115 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005116 dump += StringPrintf(", age=%" PRId64 "ms\n",
5117 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005118 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005119 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005120 }
5121
5122 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005123 if (!mInboundQueue.empty()) {
5124 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005125 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005126 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005127 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005128 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005129 }
5130 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005131 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005132 }
5133
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005134 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005135 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005136 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5137 const KeyReplacement& replacement = pair.first;
5138 int32_t newKeyCode = pair.second;
5139 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005140 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005141 }
5142 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005143 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005144 }
5145
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005146 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005147 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005148 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005149 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005150 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005151 connection->inputChannel->getFd().get(),
5152 connection->getInputChannelName().c_str(),
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005153 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005154 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005155
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005156 if (!connection->outboundQueue.empty()) {
5157 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5158 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005159 dump += dumpQueue(connection->outboundQueue, currentTime);
5160
Michael Wrightd02c5b62014-02-10 15:10:22 -08005161 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005162 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005163 }
5164
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005165 if (!connection->waitQueue.empty()) {
5166 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5167 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005168 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005169 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005170 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005171 }
5172 }
5173 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005174 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005175 }
5176
5177 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005178 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5179 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005180 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005181 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005182 }
5183
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005184 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005185 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5186 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5187 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005188 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005189 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005190}
5191
Michael Wright3dd60e22019-03-27 22:06:44 +00005192void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5193 const size_t numMonitors = monitors.size();
5194 for (size_t i = 0; i < numMonitors; i++) {
5195 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005196 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005197 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5198 dump += "\n";
5199 }
5200}
5201
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005202class LooperEventCallback : public LooperCallback {
5203public:
5204 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5205 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5206
5207private:
5208 std::function<int(int events)> mCallback;
5209};
5210
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005211Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Garfield Tan15601662020-09-22 15:32:38 -07005212#if DEBUG_CHANNEL_CREATION
5213 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005214#endif
5215
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005216 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005217 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005218 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005219
5220 if (result) {
5221 return base::Error(result) << "Failed to open input channel pair with name " << name;
5222 }
5223
Michael Wrightd02c5b62014-02-10 15:10:22 -08005224 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005225 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005226 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005227 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005228 sp<Connection> connection =
5229 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005230
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005231 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5232 ALOGE("Created a new connection, but the token %p is already known", token.get());
5233 }
5234 mConnectionsByToken.emplace(token, connection);
5235
5236 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5237 this, std::placeholders::_1, token);
5238
5239 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005240 } // release lock
5241
5242 // Wake the looper because some connections have changed.
5243 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005244 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005245}
5246
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005247Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5248 bool isGestureMonitor,
5249 const std::string& name,
5250 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005251 std::shared_ptr<InputChannel> serverChannel;
5252 std::unique_ptr<InputChannel> clientChannel;
5253 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5254 if (result) {
5255 return base::Error(result) << "Failed to open input channel pair with name " << name;
5256 }
5257
Michael Wright3dd60e22019-03-27 22:06:44 +00005258 { // acquire lock
5259 std::scoped_lock _l(mLock);
5260
5261 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005262 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5263 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005264 }
5265
Garfield Tan15601662020-09-22 15:32:38 -07005266 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005267 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005268 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005269
5270 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5271 ALOGE("Created a new connection, but the token %p is already known", token.get());
5272 }
5273 mConnectionsByToken.emplace(token, connection);
5274 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5275 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005276
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005277 auto& monitorsByDisplay =
5278 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005279 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005280
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005281 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Siarhei Vishniakouc961c742021-05-19 19:16:59 +00005282 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5283 displayId, toString(isGestureMonitor), pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005284 }
Garfield Tan15601662020-09-22 15:32:38 -07005285
Michael Wright3dd60e22019-03-27 22:06:44 +00005286 // Wake the looper because some connections have changed.
5287 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005288 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005289}
5290
Garfield Tan15601662020-09-22 15:32:38 -07005291status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005292 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005293 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005294
Garfield Tan15601662020-09-22 15:32:38 -07005295 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005296 if (status) {
5297 return status;
5298 }
5299 } // release lock
5300
5301 // Wake the poll loop because removing the connection may have changed the current
5302 // synchronization state.
5303 mLooper->wake();
5304 return OK;
5305}
5306
Garfield Tan15601662020-09-22 15:32:38 -07005307status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5308 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005309 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005310 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005311 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005312 return BAD_VALUE;
5313 }
5314
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005315 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005316
Michael Wrightd02c5b62014-02-10 15:10:22 -08005317 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005318 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005319 }
5320
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005321 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005322
5323 nsecs_t currentTime = now();
5324 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5325
5326 connection->status = Connection::STATUS_ZOMBIE;
5327 return OK;
5328}
5329
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005330void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5331 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5332 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005333}
5334
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005335void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005336 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005337 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005338 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005339 std::vector<Monitor>& monitors = it->second;
5340 const size_t numMonitors = monitors.size();
5341 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005342 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005343 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5344 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005345 monitors.erase(monitors.begin() + i);
5346 break;
5347 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005348 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005349 if (monitors.empty()) {
5350 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005351 } else {
5352 ++it;
5353 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005354 }
5355}
5356
Michael Wright3dd60e22019-03-27 22:06:44 +00005357status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5358 { // acquire lock
5359 std::scoped_lock _l(mLock);
5360 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5361
5362 if (!foundDisplayId) {
5363 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5364 return BAD_VALUE;
5365 }
5366 int32_t displayId = foundDisplayId.value();
5367
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005368 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5369 mTouchStatesByDisplay.find(displayId);
5370 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005371 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5372 return BAD_VALUE;
5373 }
5374
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005375 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005376 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005377 std::optional<int32_t> foundDeviceId;
5378 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005379 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005380 requestingChannel = touchedMonitor.monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005381 foundDeviceId = state.deviceId;
5382 }
5383 }
5384 if (!foundDeviceId || !state.down) {
5385 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005386 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005387 return BAD_VALUE;
5388 }
5389 int32_t deviceId = foundDeviceId.value();
5390
5391 // Send cancel events to all the input channels we're stealing from.
5392 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005393 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005394 options.deviceId = deviceId;
5395 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005396 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005397 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005398 std::shared_ptr<InputChannel> channel =
5399 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005400 if (channel != nullptr) {
5401 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005402 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005403 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005404 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005405 canceledWindows += "]";
5406 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5407 canceledWindows.c_str());
5408
Michael Wright3dd60e22019-03-27 22:06:44 +00005409 // Then clear the current touch state so we stop dispatching to them as well.
5410 state.filterNonMonitors();
5411 }
5412 return OK;
5413}
5414
Prabir Pradhan99987712020-11-10 18:43:05 -08005415void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5416 { // acquire lock
5417 std::scoped_lock _l(mLock);
5418 if (DEBUG_FOCUS) {
chaviw3277faf2021-05-19 16:45:23 -05005419 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005420 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5421 windowHandle != nullptr ? windowHandle->getName().c_str()
5422 : "token without window");
5423 }
5424
Vishnu Nairc519ff72021-01-21 08:23:08 -08005425 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005426 if (focusedToken != windowToken) {
5427 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5428 enabled ? "enable" : "disable");
5429 return;
5430 }
5431
Prabir Pradhanac483a62021-08-06 14:01:18 +00005432 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08005433 ALOGW("Ignoring request to %s Pointer Capture: "
5434 "window has %s requested pointer capture.",
5435 enabled ? "enable" : "disable", enabled ? "already" : "not");
5436 return;
5437 }
5438
Prabir Pradhan99987712020-11-10 18:43:05 -08005439 setPointerCaptureLocked(enabled);
5440 } // release lock
5441
5442 // Wake the thread to process command entries.
5443 mLooper->wake();
5444}
5445
Michael Wright3dd60e22019-03-27 22:06:44 +00005446std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5447 const sp<IBinder>& token) {
5448 for (const auto& it : mGestureMonitorsByDisplay) {
5449 const std::vector<Monitor>& monitors = it.second;
5450 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005451 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005452 return it.first;
5453 }
5454 }
5455 }
5456 return std::nullopt;
5457}
5458
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005459std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5460 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5461 if (gesturePid.has_value()) {
5462 return gesturePid;
5463 }
5464 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5465}
5466
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005467sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005468 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005469 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005470 }
5471
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005472 for (const auto& [token, connection] : mConnectionsByToken) {
5473 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005474 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005475 }
5476 }
Robert Carr4e670e52018-08-15 13:26:12 -07005477
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005478 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005479}
5480
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005481std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5482 sp<Connection> connection = getConnectionLocked(connectionToken);
5483 if (connection == nullptr) {
5484 return "<nullptr>";
5485 }
5486 return connection->getInputChannelName();
5487}
5488
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005489void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005490 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005491 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005492}
5493
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005494void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5495 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10005496 bool handled, nsecs_t consumeTime) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005497 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5498 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005499 commandEntry->connection = connection;
5500 commandEntry->eventTime = currentTime;
5501 commandEntry->seq = seq;
5502 commandEntry->handled = handled;
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10005503 commandEntry->consumeTime = consumeTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005504 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005505}
5506
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005507void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5508 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005509 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005510 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005511
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005512 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5513 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005514 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005515 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005516}
5517
Vishnu Nairad321cd2020-08-20 16:40:21 -07005518void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5519 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005520 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5521 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005522 commandEntry->oldToken = oldToken;
5523 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005524 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005525}
5526
arthurhungf452d0b2021-01-06 00:19:52 +08005527void InputDispatcher::notifyDropWindowLocked(const sp<IBinder>& token, float x, float y) {
5528 std::unique_ptr<CommandEntry> commandEntry =
5529 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyDropWindowLockedInterruptible);
5530 commandEntry->newToken = token;
5531 commandEntry->x = x;
5532 commandEntry->y = y;
5533 postCommandLocked(std::move(commandEntry));
5534}
5535
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005536void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5537 if (connection == nullptr) {
5538 LOG_ALWAYS_FATAL("Caller must check for nullness");
5539 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005540 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5541 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005542 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005543 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005544 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005545 return;
5546 }
5547 /**
5548 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5549 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5550 * has changed. This could cause newer entries to time out before the already dispatched
5551 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5552 * processes the events linearly. So providing information about the oldest entry seems to be
5553 * most useful.
5554 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005555 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005556 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5557 std::string reason =
5558 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005559 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005560 ns2ms(currentWait),
5561 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005562 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005563 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005564
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005565 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5566
5567 // Stop waking up for events on this connection, it is already unresponsive
5568 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005569}
5570
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005571void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5572 std::string reason =
5573 StringPrintf("%s does not have a focused window", application->getName().c_str());
5574 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005575
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005576 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5577 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5578 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005579 postCommandLocked(std::move(commandEntry));
5580}
5581
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005582void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5583 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5584 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5585 commandEntry->obscuringPackage = obscuringPackage;
5586 postCommandLocked(std::move(commandEntry));
5587}
5588
chaviw3277faf2021-05-19 16:45:23 -05005589void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005590 const std::string& reason) {
5591 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5592 updateLastAnrStateLocked(windowLabel, reason);
5593}
5594
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005595void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5596 const std::string& reason) {
5597 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005598 updateLastAnrStateLocked(windowLabel, reason);
5599}
5600
5601void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5602 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005603 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005604 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005605 struct tm tm;
5606 localtime_r(&t, &tm);
5607 char timestr[64];
5608 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005609 mLastAnrState.clear();
5610 mLastAnrState += INDENT "ANR:\n";
5611 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005612 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5613 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005614 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005615}
5616
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005617void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005618 mLock.unlock();
5619
5620 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5621
5622 mLock.lock();
5623}
5624
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005625void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005626 sp<Connection> connection = commandEntry->connection;
5627
5628 if (connection->status != Connection::STATUS_ZOMBIE) {
5629 mLock.unlock();
5630
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005631 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005632
5633 mLock.lock();
5634 }
5635}
5636
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005637void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005638 sp<IBinder> oldToken = commandEntry->oldToken;
5639 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005640 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005641 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005642 mLock.lock();
5643}
5644
arthurhungf452d0b2021-01-06 00:19:52 +08005645void InputDispatcher::doNotifyDropWindowLockedInterruptible(CommandEntry* commandEntry) {
5646 sp<IBinder> newToken = commandEntry->newToken;
5647 mLock.unlock();
5648 mPolicy->notifyDropWindow(newToken, commandEntry->x, commandEntry->y);
5649 mLock.lock();
5650}
5651
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005652void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005653 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005654
5655 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5656
5657 mLock.lock();
5658}
5659
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005660void InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005661 mLock.unlock();
5662
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005663 mPolicy->notifyWindowUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005664
5665 mLock.lock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005666}
5667
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005668void InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005669 mLock.unlock();
5670
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005671 mPolicy->notifyMonitorUnresponsive(commandEntry->pid, commandEntry->reason);
5672
5673 mLock.lock();
5674}
5675
5676void InputDispatcher::doNotifyWindowResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5677 mLock.unlock();
5678
5679 mPolicy->notifyWindowResponsive(commandEntry->connectionToken);
5680
5681 mLock.lock();
5682}
5683
5684void InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5685 mLock.unlock();
5686
5687 mPolicy->notifyMonitorResponsive(commandEntry->pid);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005688
5689 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005690}
5691
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005692void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5693 mLock.unlock();
5694
5695 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5696
5697 mLock.lock();
5698}
5699
Michael Wrightd02c5b62014-02-10 15:10:22 -08005700void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5701 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005702 KeyEntry& entry = *(commandEntry->keyEntry);
5703 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005704
5705 mLock.unlock();
5706
Michael Wright2b3c3302018-03-02 17:19:13 +00005707 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005708 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005709 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005710 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5711 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005712 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005713 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005714
5715 mLock.lock();
5716
5717 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005718 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005719 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005720 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005721 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005722 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5723 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005724 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005725}
5726
chaviwfd6d3512019-03-25 13:23:49 -07005727void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5728 mLock.unlock();
5729 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5730 mLock.lock();
5731}
5732
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005733/**
5734 * Connection is responsive if it has no events in the waitQueue that are older than the
5735 * current time.
5736 */
5737static bool isConnectionResponsive(const Connection& connection) {
5738 const nsecs_t currentTime = now();
5739 for (const DispatchEntry* entry : connection.waitQueue) {
5740 if (entry->timeoutTime < currentTime) {
5741 return false;
5742 }
5743 }
5744 return true;
5745}
5746
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005747void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005748 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005749 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005750 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005751 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005752
5753 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005754 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005755 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005756 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005757 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005758 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005759 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005760 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005761 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5762 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005763 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005764 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5765 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5766 connection->inputChannel->getConnectionToken(),
5767 dispatchEntry->deliveryTime, commandEntry->consumeTime,
5768 finishTime);
5769 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005770
5771 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005772 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005773 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005774 restartEvent =
5775 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005776 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005777 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005778 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5779 handled);
5780 } else {
5781 restartEvent = false;
5782 }
5783
5784 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005785 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005786 // contents of the wait queue to have been drained, so we need to double-check
5787 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005788 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5789 if (dispatchEntryIt != connection->waitQueue.end()) {
5790 dispatchEntry = *dispatchEntryIt;
5791 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005792 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5793 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005794 if (!connection->responsive) {
5795 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005796 if (connection->responsive) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005797 // The connection was unresponsive, and now it's responsive.
5798 processConnectionResponsiveLocked(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005799 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005800 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005801 traceWaitQueueLength(*connection);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005802 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005803 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005804 traceOutboundQueueLength(*connection);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005805 } else {
5806 releaseDispatchEntry(dispatchEntry);
5807 }
5808 }
5809
5810 // Start the next dispatch cycle for this connection.
5811 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005812}
5813
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005814void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
5815 std::unique_ptr<CommandEntry> monitorUnresponsiveCommand = std::make_unique<CommandEntry>(
5816 &InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible);
5817 monitorUnresponsiveCommand->pid = pid;
5818 monitorUnresponsiveCommand->reason = std::move(reason);
5819 postCommandLocked(std::move(monitorUnresponsiveCommand));
5820}
5821
5822void InputDispatcher::sendWindowUnresponsiveCommandLocked(sp<IBinder> connectionToken,
5823 std::string reason) {
5824 std::unique_ptr<CommandEntry> windowUnresponsiveCommand = std::make_unique<CommandEntry>(
5825 &InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible);
5826 windowUnresponsiveCommand->connectionToken = std::move(connectionToken);
5827 windowUnresponsiveCommand->reason = std::move(reason);
5828 postCommandLocked(std::move(windowUnresponsiveCommand));
5829}
5830
5831void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
5832 std::unique_ptr<CommandEntry> monitorResponsiveCommand = std::make_unique<CommandEntry>(
5833 &InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible);
5834 monitorResponsiveCommand->pid = pid;
5835 postCommandLocked(std::move(monitorResponsiveCommand));
5836}
5837
5838void InputDispatcher::sendWindowResponsiveCommandLocked(sp<IBinder> connectionToken) {
5839 std::unique_ptr<CommandEntry> windowResponsiveCommand = std::make_unique<CommandEntry>(
5840 &InputDispatcher::doNotifyWindowResponsiveLockedInterruptible);
5841 windowResponsiveCommand->connectionToken = std::move(connectionToken);
5842 postCommandLocked(std::move(windowResponsiveCommand));
5843}
5844
5845/**
5846 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5847 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5848 * command entry to the command queue.
5849 */
5850void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5851 std::string reason) {
5852 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5853 if (connection.monitor) {
5854 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5855 reason.c_str());
5856 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5857 if (!pid.has_value()) {
5858 ALOGE("Could not find unresponsive monitor for connection %s",
5859 connection.inputChannel->getName().c_str());
5860 return;
5861 }
5862 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5863 return;
5864 }
5865 // If not a monitor, must be a window
5866 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5867 reason.c_str());
5868 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5869}
5870
5871/**
5872 * Tell the policy that a connection has become responsive so that it can stop ANR.
5873 */
5874void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5875 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5876 if (connection.monitor) {
5877 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5878 if (!pid.has_value()) {
5879 ALOGE("Could not find responsive monitor for connection %s",
5880 connection.inputChannel->getName().c_str());
5881 return;
5882 }
5883 sendMonitorResponsiveCommandLocked(pid.value());
5884 return;
5885 }
5886 // If not a monitor, must be a window
5887 sendWindowResponsiveCommandLocked(connectionToken);
5888}
5889
Michael Wrightd02c5b62014-02-10 15:10:22 -08005890bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005891 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005892 KeyEntry& keyEntry, bool handled) {
5893 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005894 if (!handled) {
5895 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005896 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005897 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005898 return false;
5899 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005900
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005901 // Get the fallback key state.
5902 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005903 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005904 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005905 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005906 connection->inputState.removeFallbackKey(originalKeyCode);
5907 }
5908
5909 if (handled || !dispatchEntry->hasForegroundTarget()) {
5910 // If the application handles the original key for which we previously
5911 // generated a fallback or if the window is not a foreground window,
5912 // then cancel the associated fallback key, if any.
5913 if (fallbackKeyCode != -1) {
5914 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005915#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005916 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005917 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005918 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005919#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005920 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005921 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005922
5923 mLock.unlock();
5924
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005925 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005926 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005927
5928 mLock.lock();
5929
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005930 // Cancel the fallback key.
5931 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005932 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005933 "application handled the original non-fallback key "
5934 "or is no longer a foreground target, "
5935 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005936 options.keyCode = fallbackKeyCode;
5937 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005938 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005939 connection->inputState.removeFallbackKey(originalKeyCode);
5940 }
5941 } else {
5942 // If the application did not handle a non-fallback key, first check
5943 // that we are in a good state to perform unhandled key event processing
5944 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005945 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005946 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005947#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005948 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005949 "since this is not an initial down. "
5950 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005951 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005952#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005953 return false;
5954 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005955
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005956 // Dispatch the unhandled key to the policy.
5957#if DEBUG_OUTBOUND_EVENT_DETAILS
5958 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005959 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005960 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005961#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005962 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005963
5964 mLock.unlock();
5965
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005966 bool fallback =
5967 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005968 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005969
5970 mLock.lock();
5971
5972 if (connection->status != Connection::STATUS_NORMAL) {
5973 connection->inputState.removeFallbackKey(originalKeyCode);
5974 return false;
5975 }
5976
5977 // Latch the fallback keycode for this key on an initial down.
5978 // The fallback keycode cannot change at any other point in the lifecycle.
5979 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005980 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005981 fallbackKeyCode = event.getKeyCode();
5982 } else {
5983 fallbackKeyCode = AKEYCODE_UNKNOWN;
5984 }
5985 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5986 }
5987
5988 ALOG_ASSERT(fallbackKeyCode != -1);
5989
5990 // Cancel the fallback key if the policy decides not to send it anymore.
5991 // We will continue to dispatch the key to the policy but we will no
5992 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005993 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5994 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005995#if DEBUG_OUTBOUND_EVENT_DETAILS
5996 if (fallback) {
5997 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005998 "as a fallback for %d, but on the DOWN it had requested "
5999 "to send %d instead. Fallback canceled.",
6000 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006001 } else {
6002 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006003 "but on the DOWN it had requested to send %d. "
6004 "Fallback canceled.",
6005 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006006 }
6007#endif
6008
6009 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
6010 "canceling fallback, policy no longer desires it");
6011 options.keyCode = fallbackKeyCode;
6012 synthesizeCancelationEventsForConnectionLocked(connection, options);
6013
6014 fallback = false;
6015 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006016 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006017 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006018 }
6019 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006020
6021#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006022 {
6023 std::string msg;
6024 const KeyedVector<int32_t, int32_t>& fallbackKeys =
6025 connection->inputState.getFallbackKeys();
6026 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006027 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006028 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006029 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006030 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006031 }
6032#endif
6033
6034 if (fallback) {
6035 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006036 keyEntry.eventTime = event.getEventTime();
6037 keyEntry.deviceId = event.getDeviceId();
6038 keyEntry.source = event.getSource();
6039 keyEntry.displayId = event.getDisplayId();
6040 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
6041 keyEntry.keyCode = fallbackKeyCode;
6042 keyEntry.scanCode = event.getScanCode();
6043 keyEntry.metaState = event.getMetaState();
6044 keyEntry.repeatCount = event.getRepeatCount();
6045 keyEntry.downTime = event.getDownTime();
6046 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006047
6048#if DEBUG_OUTBOUND_EVENT_DETAILS
6049 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006050 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006051 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006052#endif
6053 return true; // restart the event
6054 } else {
6055#if DEBUG_OUTBOUND_EVENT_DETAILS
6056 ALOGD("Unhandled key event: No fallback key.");
6057#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006058
6059 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006060 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006061 }
6062 }
6063 return false;
6064}
6065
6066bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006067 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006068 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006069 return false;
6070}
6071
6072void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
6073 mLock.unlock();
6074
Sean Stoutb4e0a592021-02-23 07:34:53 -08006075 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType,
6076 commandEntry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006077
6078 mLock.lock();
6079}
6080
Michael Wrightd02c5b62014-02-10 15:10:22 -08006081void InputDispatcher::traceInboundQueueLengthLocked() {
6082 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006083 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006084 }
6085}
6086
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006087void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006088 if (ATRACE_ENABLED()) {
6089 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006090 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6091 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006092 }
6093}
6094
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006095void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006096 if (ATRACE_ENABLED()) {
6097 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006098 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6099 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006100 }
6101}
6102
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006103void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006104 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006105
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006106 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006107 dumpDispatchStateLocked(dump);
6108
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006109 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006110 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006111 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006112 }
6113}
6114
6115void InputDispatcher::monitor() {
6116 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006117 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006118 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006119 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006120}
6121
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006122/**
6123 * Wake up the dispatcher and wait until it processes all events and commands.
6124 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6125 * this method can be safely called from any thread, as long as you've ensured that
6126 * the work you are interested in completing has already been queued.
6127 */
6128bool InputDispatcher::waitForIdle() {
6129 /**
6130 * Timeout should represent the longest possible time that a device might spend processing
6131 * events and commands.
6132 */
6133 constexpr std::chrono::duration TIMEOUT = 100ms;
6134 std::unique_lock lock(mLock);
6135 mLooper->wake();
6136 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6137 return result == std::cv_status::no_timeout;
6138}
6139
Vishnu Naire798b472020-07-23 13:52:21 -07006140/**
6141 * Sets focus to the window identified by the token. This must be called
6142 * after updating any input window handles.
6143 *
6144 * Params:
6145 * request.token - input channel token used to identify the window that should gain focus.
6146 * request.focusedToken - the token that the caller expects currently to be focused. If the
6147 * specified token does not match the currently focused window, this request will be dropped.
6148 * If the specified focused token matches the currently focused window, the call will succeed.
6149 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6150 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6151 * when requesting the focus change. This determines which request gets
6152 * precedence if there is a focus change request from another source such as pointer down.
6153 */
Vishnu Nair958da932020-08-21 17:12:37 -07006154void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6155 { // acquire lock
6156 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006157 std::optional<FocusResolver::FocusChanges> changes =
6158 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6159 if (changes) {
6160 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006161 }
6162 } // release lock
6163 // Wake up poll loop since it may need to make new input dispatching choices.
6164 mLooper->wake();
6165}
6166
Vishnu Nairc519ff72021-01-21 08:23:08 -08006167void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6168 if (changes.oldFocus) {
6169 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006170 if (focusedInputChannel) {
6171 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6172 "focus left window");
6173 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006174 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006175 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006176 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006177 if (changes.newFocus) {
6178 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006179 }
6180
Prabir Pradhan99987712020-11-10 18:43:05 -08006181 // If a window has pointer capture, then it must have focus. We need to ensure that this
6182 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6183 // If the window loses focus before it loses pointer capture, then the window can be in a state
6184 // where it has pointer capture but not focus, violating the contract. Therefore we must
6185 // dispatch the pointer capture event before the focus event. Since focus events are added to
6186 // the front of the queue (above), we add the pointer capture event to the front of the queue
6187 // after the focus events are added. This ensures the pointer capture event ends up at the
6188 // front.
6189 disablePointerCaptureForcedLocked();
6190
Vishnu Nairc519ff72021-01-21 08:23:08 -08006191 if (mFocusedDisplayId == changes.displayId) {
6192 notifyFocusChangedLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006193 }
6194}
Vishnu Nair958da932020-08-21 17:12:37 -07006195
Prabir Pradhan99987712020-11-10 18:43:05 -08006196void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhanac483a62021-08-06 14:01:18 +00006197 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006198 return;
6199 }
6200
6201 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6202
Prabir Pradhanac483a62021-08-06 14:01:18 +00006203 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006204 setPointerCaptureLocked(false);
6205 }
6206
6207 if (!mWindowTokenWithPointerCapture) {
6208 // No need to send capture changes because no window has capture.
6209 return;
6210 }
6211
6212 if (mPendingEvent != nullptr) {
6213 // Move the pending event to the front of the queue. This will give the chance
6214 // for the pending event to be dropped if it is a captured event.
6215 mInboundQueue.push_front(mPendingEvent);
6216 mPendingEvent = nullptr;
6217 }
6218
6219 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhanac483a62021-08-06 14:01:18 +00006220 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006221 mInboundQueue.push_front(std::move(entry));
6222}
6223
Prabir Pradhan99987712020-11-10 18:43:05 -08006224void InputDispatcher::setPointerCaptureLocked(bool enabled) {
Prabir Pradhanac483a62021-08-06 14:01:18 +00006225 mCurrentPointerCaptureRequest.enable = enabled;
6226 mCurrentPointerCaptureRequest.seq++;
Prabir Pradhan99987712020-11-10 18:43:05 -08006227 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
6228 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
Prabir Pradhanac483a62021-08-06 14:01:18 +00006229 commandEntry->pointerCaptureRequest = mCurrentPointerCaptureRequest;
Prabir Pradhan99987712020-11-10 18:43:05 -08006230 postCommandLocked(std::move(commandEntry));
6231}
6232
6233void InputDispatcher::doSetPointerCaptureLockedInterruptible(
6234 android::inputdispatcher::CommandEntry* commandEntry) {
6235 mLock.unlock();
6236
Prabir Pradhanac483a62021-08-06 14:01:18 +00006237 mPolicy->setPointerCapture(commandEntry->pointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006238
6239 mLock.lock();
6240}
6241
Vishnu Nair599f1412021-06-21 10:39:58 -07006242void InputDispatcher::displayRemoved(int32_t displayId) {
6243 { // acquire lock
6244 std::scoped_lock _l(mLock);
6245 // Set an empty list to remove all handles from the specific display.
6246 setInputWindowsLocked(/* window handles */ {}, displayId);
6247 setFocusedApplicationLocked(displayId, nullptr);
6248 // Call focus resolver to clean up stale requests. This must be called after input windows
6249 // have been removed for the removed display.
6250 mFocusResolver.displayRemoved(displayId);
6251 } // release lock
6252
6253 // Wake up poll loop since it may need to make new input dispatching choices.
6254 mLooper->wake();
6255}
6256
chaviw15fab6f2021-06-07 14:15:52 -05006257void InputDispatcher::onWindowInfosChanged(const std::vector<gui::WindowInfo>& windowInfos) {
6258 // The listener sends the windows as a flattened array. Separate the windows by display for
6259 // more convenient parsing.
6260 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
6261
6262 for (const auto& info : windowInfos) {
6263 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
6264 handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
6265 }
6266 setInputWindows(handlesPerDisplay);
6267}
6268
Garfield Tane84e6f92019-08-29 17:28:41 -07006269} // namespace android::inputdispatcher