blob: fac5b9dcc14921f7f3deb532db2dac79fbde1806 [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>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080058#include <input/InputDevice.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070059#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000060#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070061#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010062#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070063#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080064
Michael Wright44753b12020-07-08 13:48:11 +010065#include <cerrno>
66#include <cinttypes>
67#include <climits>
68#include <cstddef>
69#include <ctime>
70#include <queue>
71#include <sstream>
72
73#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070074#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010075
Michael Wrightd02c5b62014-02-10 15:10:22 -080076#define INDENT " "
77#define INDENT2 " "
78#define INDENT3 " "
79#define INDENT4 " "
80
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080081using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000082using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080083using android::base::StringPrintf;
chaviw98318de2021-05-19 16:45:23 -050084using android::gui::FocusRequest;
85using android::gui::TouchOcclusionMode;
86using android::gui::WindowInfo;
87using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080088using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100089using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080090using android::os::InputEventInjectionResult;
91using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100092using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080093
Garfield Tane84e6f92019-08-29 17:28:41 -070094namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080095
Prabir Pradhancef936d2021-07-21 16:17:52 +000096namespace {
97
98// Temporarily releases a held mutex for the lifetime of the instance.
99// Named to match std::scoped_lock
100class scoped_unlock {
101public:
102 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
103 ~scoped_unlock() { mMutex.lock(); }
104
105private:
106 std::mutex& mMutex;
107};
108
109} // namespace
110
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700111// When per-window-input-rotation is enabled, InputFlinger works in the un-rotated display
112// coordinates and SurfaceFlinger includes the display rotation in the input window transforms.
113static bool isPerWindowInputRotationEnabled() {
114 static const bool PER_WINDOW_INPUT_ROTATION =
Prabir Pradhand2c9e8e2021-05-24 15:00:12 -0700115 sysprop::InputFlingerProperties::per_window_input_rotation().value_or(false);
116
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700117 return PER_WINDOW_INPUT_ROTATION;
118}
119
Michael Wrightd02c5b62014-02-10 15:10:22 -0800120// Default input dispatching timeout if there is no focused application or paused window
121// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -0800122const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
123 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
124 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800125
126// Amount of time to allow for all pending events to be processed when an app switch
127// key is on the way. This is used to preempt input dispatch and drop input events
128// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000129constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800130
131// Amount of time to allow for an event to be dispatched (measured since its eventTime)
132// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000133constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800134
Michael Wrightd02c5b62014-02-10 15:10:22 -0800135// 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 +0000136constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
137
138// Log a warning when an interception call takes longer than this to process.
139constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800140
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700141// Additional key latency in case a connection is still processing some motion events.
142// This will help with the case when a user touched a button that opens a new window,
143// and gives us the chance to dispatch the key to this new window.
144constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
145
Michael Wrightd02c5b62014-02-10 15:10:22 -0800146// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000147constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
148
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000149// Event log tags. See EventLogTags.logtags for reference
150constexpr int LOGTAG_INPUT_INTERACTION = 62000;
151constexpr int LOGTAG_INPUT_FOCUS = 62001;
152
Michael Wrightd02c5b62014-02-10 15:10:22 -0800153static inline nsecs_t now() {
154 return systemTime(SYSTEM_TIME_MONOTONIC);
155}
156
157static inline const char* toString(bool value) {
158 return value ? "true" : "false";
159}
160
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000161static inline const std::string toString(sp<IBinder> binder) {
162 if (binder == nullptr) {
163 return "<null>";
164 }
165 return StringPrintf("%p", binder.get());
166}
167
Michael Wrightd02c5b62014-02-10 15:10:22 -0800168static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700169 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
170 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800171}
172
173static bool isValidKeyAction(int32_t action) {
174 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700175 case AKEY_EVENT_ACTION_DOWN:
176 case AKEY_EVENT_ACTION_UP:
177 return true;
178 default:
179 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800180 }
181}
182
183static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700184 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185 ALOGE("Key event has invalid action code 0x%x", action);
186 return false;
187 }
188 return true;
189}
190
Michael Wright7b159c92015-05-14 14:48:03 +0100191static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800192 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700193 case AMOTION_EVENT_ACTION_DOWN:
194 case AMOTION_EVENT_ACTION_UP:
195 case AMOTION_EVENT_ACTION_CANCEL:
196 case AMOTION_EVENT_ACTION_MOVE:
197 case AMOTION_EVENT_ACTION_OUTSIDE:
198 case AMOTION_EVENT_ACTION_HOVER_ENTER:
199 case AMOTION_EVENT_ACTION_HOVER_MOVE:
200 case AMOTION_EVENT_ACTION_HOVER_EXIT:
201 case AMOTION_EVENT_ACTION_SCROLL:
202 return true;
203 case AMOTION_EVENT_ACTION_POINTER_DOWN:
204 case AMOTION_EVENT_ACTION_POINTER_UP: {
205 int32_t index = getMotionEventActionPointerIndex(action);
206 return index >= 0 && index < pointerCount;
207 }
208 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
209 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
210 return actionButton != 0;
211 default:
212 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800213 }
214}
215
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500216static int64_t millis(std::chrono::nanoseconds t) {
217 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
218}
219
Michael Wright7b159c92015-05-14 14:48:03 +0100220static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700221 const PointerProperties* pointerProperties) {
222 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800223 ALOGE("Motion event has invalid action code 0x%x", action);
224 return false;
225 }
226 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000227 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700228 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800229 return false;
230 }
231 BitSet32 pointerIdBits;
232 for (size_t i = 0; i < pointerCount; i++) {
233 int32_t id = pointerProperties[i].id;
234 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700235 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
236 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800237 return false;
238 }
239 if (pointerIdBits.hasBit(id)) {
240 ALOGE("Motion event has duplicate pointer id %d", id);
241 return false;
242 }
243 pointerIdBits.markBit(id);
244 }
245 return true;
246}
247
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000248static std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800249 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000250 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800251 }
252
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000253 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800254 bool first = true;
255 Region::const_iterator cur = region.begin();
256 Region::const_iterator const tail = region.end();
257 while (cur != tail) {
258 if (first) {
259 first = false;
260 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800261 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800262 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800263 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800264 cur++;
265 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000266 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800267}
268
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500269static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
270 constexpr size_t maxEntries = 50; // max events to print
271 constexpr size_t skipBegin = maxEntries / 2;
272 const size_t skipEnd = queue.size() - maxEntries / 2;
273 // skip from maxEntries / 2 ... size() - maxEntries/2
274 // only print from 0 .. skipBegin and then from skipEnd .. size()
275
276 std::string dump;
277 for (size_t i = 0; i < queue.size(); i++) {
278 const DispatchEntry& entry = *queue[i];
279 if (i >= skipBegin && i < skipEnd) {
280 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
281 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
282 continue;
283 }
284 dump.append(INDENT4);
285 dump += entry.eventEntry->getDescription();
286 dump += StringPrintf(", seq=%" PRIu32
287 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
288 entry.seq, entry.targetFlags, entry.resolvedAction,
289 ns2ms(currentTime - entry.eventEntry->eventTime));
290 if (entry.deliveryTime != 0) {
291 // This entry was delivered, so add information on how long we've been waiting
292 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
293 }
294 dump.append("\n");
295 }
296 return dump;
297}
298
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700299/**
300 * Find the entry in std::unordered_map by key, and return it.
301 * If the entry is not found, return a default constructed entry.
302 *
303 * Useful when the entries are vectors, since an empty vector will be returned
304 * if the entry is not found.
305 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
306 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700307template <typename K, typename V>
308static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700309 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700310 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800311}
312
chaviw98318de2021-05-19 16:45:23 -0500313static bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700314 if (first == second) {
315 return true;
316 }
317
318 if (first == nullptr || second == nullptr) {
319 return false;
320 }
321
322 return first->getToken() == second->getToken();
323}
324
chaviw98318de2021-05-19 16:45:23 -0500325static bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000326 if (first == nullptr || second == nullptr) {
327 return false;
328 }
329 return first->applicationInfo.token != nullptr &&
330 first->applicationInfo.token == second->applicationInfo.token;
331}
332
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800333static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
334 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
335}
336
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000337static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700338 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000339 int32_t inputTargetFlags) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900340 if (eventEntry->type == EventEntry::Type::MOTION) {
341 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
Prabir Pradhan664834b2021-05-20 16:00:42 -0700342 if ((motionEntry.source & AINPUT_SOURCE_CLASS_JOYSTICK) ||
343 (motionEntry.source & AINPUT_SOURCE_CLASS_POSITION)) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900344 const ui::Transform identityTransform;
Prabir Pradhan664834b2021-05-20 16:00:42 -0700345 // Use identity transform for joystick and position-based (touchpad) events because they
346 // don't depend on the window transform.
yunho.shinf4a80b82020-11-16 21:13:57 +0900347 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700348 1.0f /*globalScaleFactor*/,
Evan Rosky09576692021-07-01 12:22:09 -0700349 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700350 inputTarget.displaySize);
yunho.shinf4a80b82020-11-16 21:13:57 +0900351 }
352 }
353
chaviw1ff3d1e2020-07-01 15:53:47 -0700354 if (inputTarget.useDefaultPointerTransform()) {
355 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700356 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700357 inputTarget.globalScaleFactor,
Evan Rosky09576692021-07-01 12:22:09 -0700358 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700359 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000360 }
361
362 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
363 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
364
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700365 std::vector<PointerCoords> pointerCoords;
366 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000367
368 // Use the first pointer information to normalize all other pointers. This could be any pointer
369 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700370 // uses the transform for the normalized pointer.
371 const ui::Transform& firstPointerTransform =
372 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
373 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000374
375 // Iterate through all pointers in the event to normalize against the first.
376 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
377 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
378 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700379 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000380
381 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700382 // First, apply the current pointer's transform to update the coordinates into
383 // window space.
384 pointerCoords[pointerIndex].transform(currTransform);
385 // Next, apply the inverse transform of the normalized coordinates so the
386 // current coordinates are transformed into the normalized coordinate space.
387 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000388 }
389
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700390 std::unique_ptr<MotionEntry> combinedMotionEntry =
391 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
392 motionEntry.deviceId, motionEntry.source,
393 motionEntry.displayId, motionEntry.policyFlags,
394 motionEntry.action, motionEntry.actionButton,
395 motionEntry.flags, motionEntry.metaState,
396 motionEntry.buttonState, motionEntry.classification,
397 motionEntry.edgeFlags, motionEntry.xPrecision,
398 motionEntry.yPrecision, motionEntry.xCursorPosition,
399 motionEntry.yCursorPosition, motionEntry.downTime,
400 motionEntry.pointerCount, motionEntry.pointerProperties,
401 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000402
403 if (motionEntry.injectionState) {
404 combinedMotionEntry->injectionState = motionEntry.injectionState;
405 combinedMotionEntry->injectionState->refCount += 1;
406 }
407
408 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700409 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Evan Rosky84f07f02021-04-16 10:42:42 -0700410 firstPointerTransform, inputTarget.globalScaleFactor,
Evan Rosky09576692021-07-01 12:22:09 -0700411 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700412 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000413 return dispatchEntry;
414}
415
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700416static void addGestureMonitors(const std::vector<Monitor>& monitors,
417 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
418 float yOffset = 0) {
419 if (monitors.empty()) {
420 return;
421 }
422 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
423 for (const Monitor& monitor : monitors) {
424 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
425 }
426}
427
Garfield Tan15601662020-09-22 15:32:38 -0700428static status_t openInputChannelPair(const std::string& name,
429 std::shared_ptr<InputChannel>& serverChannel,
430 std::unique_ptr<InputChannel>& clientChannel) {
431 std::unique_ptr<InputChannel> uniqueServerChannel;
432 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
433
434 serverChannel = std::move(uniqueServerChannel);
435 return result;
436}
437
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500438template <typename T>
439static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
440 if (lhs == nullptr && rhs == nullptr) {
441 return true;
442 }
443 if (lhs == nullptr || rhs == nullptr) {
444 return false;
445 }
446 return *lhs == *rhs;
447}
448
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000449static sp<IPlatformCompatNative> getCompatService() {
450 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
451 if (service == nullptr) {
452 ALOGE("Failed to link to compat service");
453 return nullptr;
454 }
455 return interface_cast<IPlatformCompatNative>(service);
456}
457
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000458static KeyEvent createKeyEvent(const KeyEntry& entry) {
459 KeyEvent event;
460 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
461 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
462 entry.repeatCount, entry.downTime, entry.eventTime);
463 return event;
464}
465
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000466static std::optional<int32_t> findMonitorPidByToken(
467 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
468 const sp<IBinder>& token) {
469 for (const auto& it : monitorsByDisplay) {
470 const std::vector<Monitor>& monitors = it.second;
471 for (const Monitor& monitor : monitors) {
472 if (monitor.inputChannel->getConnectionToken() == token) {
473 return monitor.pid;
474 }
475 }
476 }
477 return std::nullopt;
478}
479
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000480static bool shouldReportMetricsForConnection(const Connection& connection) {
481 // Do not keep track of gesture monitors. They receive every event and would disproportionately
482 // affect the statistics.
483 if (connection.monitor) {
484 return false;
485 }
486 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
487 if (!connection.responsive) {
488 return false;
489 }
490 return true;
491}
492
493static bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry,
494 const Connection& connection) {
495 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
496 const int32_t& inputEventId = eventEntry.id;
497 if (inputEventId != dispatchEntry.resolvedEventId) {
498 // Event was transmuted
499 return false;
500 }
501 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
502 return false;
503 }
504 // Only track latency for events that originated from hardware
505 if (eventEntry.isSynthesized()) {
506 return false;
507 }
508 const EventEntry::Type& inputEventEntryType = eventEntry.type;
509 if (inputEventEntryType == EventEntry::Type::KEY) {
510 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
511 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
512 return false;
513 }
514 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
515 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
516 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
517 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
518 return false;
519 }
520 } else {
521 // Not a key or a motion
522 return false;
523 }
524 if (!shouldReportMetricsForConnection(connection)) {
525 return false;
526 }
527 return true;
528}
529
Prabir Pradhancef936d2021-07-21 16:17:52 +0000530/**
531 * Connection is responsive if it has no events in the waitQueue that are older than the
532 * current time.
533 */
534static bool isConnectionResponsive(const Connection& connection) {
535 const nsecs_t currentTime = now();
536 for (const DispatchEntry* entry : connection.waitQueue) {
537 if (entry->timeoutTime < currentTime) {
538 return false;
539 }
540 }
541 return true;
542}
543
Michael Wrightd02c5b62014-02-10 15:10:22 -0800544// --- InputDispatcher ---
545
Garfield Tan00f511d2019-06-12 16:55:40 -0700546InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
547 : mPolicy(policy),
548 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700549 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800550 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700551 mAppSwitchSawKeyDown(false),
552 mAppSwitchDueTime(LONG_LONG_MAX),
553 mNextUnblockedEvent(nullptr),
554 mDispatchEnabled(false),
555 mDispatchFrozen(false),
556 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800557 // mInTouchMode will be initialized by the WindowManager to the default device config.
558 // To avoid leaking stack in case that call never comes, and for tests,
559 // initialize it here anyways.
560 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100561 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000562 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800563 mFocusedWindowRequestedPointerCapture(false),
564 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000565 mLatencyAggregator(),
566 mLatencyTracker(&mLatencyAggregator),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000567 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800568 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800569 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800570
Yi Kong9b14ac62018-07-17 13:48:38 -0700571 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800572
573 policy->getDispatcherConfiguration(&mConfig);
574}
575
576InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000577 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800578
Prabir Pradhancef936d2021-07-21 16:17:52 +0000579 resetKeyRepeatLocked();
580 releasePendingEventLocked();
581 drainInboundQueueLocked();
582 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800583
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000584 while (!mConnectionsByToken.empty()) {
585 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000586 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
587 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800588 }
589}
590
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700591status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700592 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700593 return ALREADY_EXISTS;
594 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700595 mThread = std::make_unique<InputThread>(
596 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
597 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700598}
599
600status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700601 if (mThread && mThread->isCallingThread()) {
602 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700603 return INVALID_OPERATION;
604 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700605 mThread.reset();
606 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700607}
608
Michael Wrightd02c5b62014-02-10 15:10:22 -0800609void InputDispatcher::dispatchOnce() {
610 nsecs_t nextWakeupTime = LONG_LONG_MAX;
611 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800612 std::scoped_lock _l(mLock);
613 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800614
615 // Run a dispatch loop if there are no pending commands.
616 // The dispatch loop might enqueue commands to run afterwards.
617 if (!haveCommandsLocked()) {
618 dispatchOnceInnerLocked(&nextWakeupTime);
619 }
620
621 // Run all pending commands if there are any.
622 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000623 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800624 nextWakeupTime = LONG_LONG_MIN;
625 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800626
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700627 // If we are still waiting for ack on some events,
628 // we might have to wake up earlier to check if an app is anr'ing.
629 const nsecs_t nextAnrCheck = processAnrsLocked();
630 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
631
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800632 // We are about to enter an infinitely long sleep, because we have no commands or
633 // pending or queued events
634 if (nextWakeupTime == LONG_LONG_MAX) {
635 mDispatcherEnteredIdle.notify_all();
636 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800637 } // release lock
638
639 // Wait for callback or timeout or wake. (make sure we round up, not down)
640 nsecs_t currentTime = now();
641 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
642 mLooper->pollOnce(timeoutMillis);
643}
644
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700645/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500646 * Raise ANR if there is no focused window.
647 * Before the ANR is raised, do a final state check:
648 * 1. The currently focused application must be the same one we are waiting for.
649 * 2. Ensure we still don't have a focused window.
650 */
651void InputDispatcher::processNoFocusedWindowAnrLocked() {
652 // Check if the application that we are waiting for is still focused.
653 std::shared_ptr<InputApplicationHandle> focusedApplication =
654 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
655 if (focusedApplication == nullptr ||
656 focusedApplication->getApplicationToken() !=
657 mAwaitedFocusedApplication->getApplicationToken()) {
658 // Unexpected because we should have reset the ANR timer when focused application changed
659 ALOGE("Waited for a focused window, but focused application has already changed to %s",
660 focusedApplication->getName().c_str());
661 return; // The focused application has changed.
662 }
663
chaviw98318de2021-05-19 16:45:23 -0500664 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500665 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
666 if (focusedWindowHandle != nullptr) {
667 return; // We now have a focused window. No need for ANR.
668 }
669 onAnrLocked(mAwaitedFocusedApplication);
670}
671
672/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700673 * Check if any of the connections' wait queues have events that are too old.
674 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
675 * Return the time at which we should wake up next.
676 */
677nsecs_t InputDispatcher::processAnrsLocked() {
678 const nsecs_t currentTime = now();
679 nsecs_t nextAnrCheck = LONG_LONG_MAX;
680 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
681 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
682 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500683 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700684 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500685 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700686 return LONG_LONG_MIN;
687 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500688 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700689 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
690 }
691 }
692
693 // Check if any connection ANRs are due
694 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
695 if (currentTime < nextAnrCheck) { // most likely scenario
696 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
697 }
698
699 // If we reached here, we have an unresponsive connection.
700 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
701 if (connection == nullptr) {
702 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
703 return nextAnrCheck;
704 }
705 connection->responsive = false;
706 // Stop waking up for this unresponsive connection
707 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000708 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700709 return LONG_LONG_MIN;
710}
711
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500712std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
chaviw98318de2021-05-19 16:45:23 -0500713 sp<WindowInfoHandle> window = getWindowHandleLocked(token);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700714 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500715 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700716 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500717 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700718}
719
Michael Wrightd02c5b62014-02-10 15:10:22 -0800720void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
721 nsecs_t currentTime = now();
722
Jeff Browndc5992e2014-04-11 01:27:26 -0700723 // Reset the key repeat timer whenever normal dispatch is suspended while the
724 // device is in a non-interactive state. This is to ensure that we abort a key
725 // repeat if the device is just coming out of sleep.
726 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800727 resetKeyRepeatLocked();
728 }
729
730 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
731 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100732 if (DEBUG_FOCUS) {
733 ALOGD("Dispatch frozen. Waiting some more.");
734 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800735 return;
736 }
737
738 // Optimize latency of app switches.
739 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
740 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
741 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
742 if (mAppSwitchDueTime < *nextWakeupTime) {
743 *nextWakeupTime = mAppSwitchDueTime;
744 }
745
746 // Ready to start a new event.
747 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700748 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700749 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800750 if (isAppSwitchDue) {
751 // The inbound queue is empty so the app switch key we were waiting
752 // for will never arrive. Stop waiting for it.
753 resetPendingAppSwitchLocked(false);
754 isAppSwitchDue = false;
755 }
756
757 // Synthesize a key repeat if appropriate.
758 if (mKeyRepeatState.lastKeyEntry) {
759 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
760 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
761 } else {
762 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
763 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
764 }
765 }
766 }
767
768 // Nothing to do if there is no pending event.
769 if (!mPendingEvent) {
770 return;
771 }
772 } else {
773 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700774 mPendingEvent = mInboundQueue.front();
775 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800776 traceInboundQueueLengthLocked();
777 }
778
779 // Poke user activity for this event.
780 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700781 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800782 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800783 }
784
785 // Now we have an event to dispatch.
786 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700787 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800788 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700789 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800790 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700791 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800792 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700793 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800794 }
795
796 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700797 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800798 }
799
800 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700801 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700802 const ConfigurationChangedEntry& typedEntry =
803 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700804 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700805 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700806 break;
807 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800808
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700809 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700810 const DeviceResetEntry& typedEntry =
811 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700812 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700813 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700814 break;
815 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800816
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100817 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700818 std::shared_ptr<FocusEntry> typedEntry =
819 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100820 dispatchFocusLocked(currentTime, typedEntry);
821 done = true;
822 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
823 break;
824 }
825
Prabir Pradhan99987712020-11-10 18:43:05 -0800826 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
827 const auto typedEntry =
828 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
829 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
830 done = true;
831 break;
832 }
833
arthurhungb89ccb02020-12-30 16:19:01 +0800834 case EventEntry::Type::DRAG: {
835 std::shared_ptr<DragEntry> typedEntry =
836 std::static_pointer_cast<DragEntry>(mPendingEvent);
837 dispatchDragLocked(currentTime, typedEntry);
838 done = true;
839 break;
840 }
841
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700842 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700843 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700844 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700845 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700846 resetPendingAppSwitchLocked(true);
847 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700848 } else if (dropReason == DropReason::NOT_DROPPED) {
849 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700850 }
851 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700852 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700853 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700854 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700855 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
856 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700857 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700858 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700859 break;
860 }
861
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700862 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700863 std::shared_ptr<MotionEntry> motionEntry =
864 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700865 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
866 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800867 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700868 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700869 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700870 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700871 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
872 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700873 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700874 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700875 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800876 }
Chris Yef59a2f42020-10-16 12:55:26 -0700877
878 case EventEntry::Type::SENSOR: {
879 std::shared_ptr<SensorEntry> sensorEntry =
880 std::static_pointer_cast<SensorEntry>(mPendingEvent);
881 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
882 dropReason = DropReason::APP_SWITCH;
883 }
884 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
885 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
886 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
887 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
888 dropReason = DropReason::STALE;
889 }
890 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
891 done = true;
892 break;
893 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800894 }
895
896 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700897 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700898 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800899 }
Michael Wright3a981722015-06-10 15:26:13 +0100900 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800901
902 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700903 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800904 }
905}
906
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700907/**
908 * Return true if the events preceding this incoming motion event should be dropped
909 * Return false otherwise (the default behaviour)
910 */
911bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700912 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700913 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700914
915 // Optimize case where the current application is unresponsive and the user
916 // decides to touch a window in a different application.
917 // If the application takes too long to catch up then we drop all events preceding
918 // the touch into the other window.
919 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700920 int32_t displayId = motionEntry.displayId;
921 int32_t x = static_cast<int32_t>(
922 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
923 int32_t y = static_cast<int32_t>(
924 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
chaviw98318de2021-05-19 16:45:23 -0500925 sp<WindowInfoHandle> touchedWindowHandle =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700926 findTouchedWindowAtLocked(displayId, x, y, nullptr);
927 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700928 touchedWindowHandle->getApplicationToken() !=
929 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700930 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700931 ALOGI("Pruning input queue because user touched a different application while waiting "
932 "for %s",
933 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700934 return true;
935 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700936
937 // Alternatively, maybe there's a gesture monitor that could handle this event
Siarhei Vishniakou64452932020-11-06 17:51:32 -0600938 std::vector<TouchedMonitor> gestureMonitors = findTouchedGestureMonitorsLocked(displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700939 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
940 sp<Connection> connection =
941 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000942 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700943 // This monitor could take more input. Drop all events preceding this
944 // event, so that gesture monitor could get a chance to receive the stream
945 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
946 "responsive gesture monitor that may handle the event",
947 mAwaitedFocusedApplication->getName().c_str());
948 return true;
949 }
950 }
951 }
952
953 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
954 // yet been processed by some connections, the dispatcher will wait for these motion
955 // events to be processed before dispatching the key event. This is because these motion events
956 // may cause a new window to be launched, which the user might expect to receive focus.
957 // To prevent waiting forever for such events, just send the key to the currently focused window
958 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
959 ALOGD("Received a new pointer down event, stop waiting for events to process and "
960 "just send the pending key event to the focused window.");
961 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700962 }
963 return false;
964}
965
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700966bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700967 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700968 mInboundQueue.push_back(std::move(newEntry));
969 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800970 traceInboundQueueLengthLocked();
971
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700972 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700973 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700974 // Optimize app switch latency.
975 // If the application takes too long to catch up then we drop all events preceding
976 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700977 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700978 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700979 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700980 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700981 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700982 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800983#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700984 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700986 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700987 mAppSwitchSawKeyDown = false;
988 needWake = true;
989 }
990 }
991 }
992 break;
993 }
994
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700995 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700996 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
997 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700998 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800999 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001000 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001001 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001002 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001003 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1004 break;
1005 }
1006 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001007 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001008 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001009 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1010 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001011 // nothing to do
1012 break;
1013 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001014 }
1015
1016 return needWake;
1017}
1018
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001019void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001020 // Do not store sensor event in recent queue to avoid flooding the queue.
1021 if (entry->type != EventEntry::Type::SENSOR) {
1022 mRecentQueue.push_back(entry);
1023 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001024 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001025 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001026 }
1027}
1028
chaviw98318de2021-05-19 16:45:23 -05001029sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1030 int32_t y, TouchState* touchState,
1031 bool addOutsideTargets,
1032 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001033 if (addOutsideTargets && touchState == nullptr) {
1034 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001035 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001036 // Traverse windows from front to back to find touched window.
chaviw98318de2021-05-19 16:45:23 -05001037 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
1038 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001039 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001040 continue;
1041 }
chaviw98318de2021-05-19 16:45:23 -05001042 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001043 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +01001044 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001045
1046 if (windowInfo->visible) {
chaviw98318de2021-05-19 16:45:23 -05001047 if (!flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
1048 bool isTouchModal = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
1049 !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001050 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
1051 // Found window.
1052 return windowHandle;
1053 }
1054 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001055
chaviw98318de2021-05-19 16:45:23 -05001056 if (addOutsideTargets && flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001057 touchState->addOrUpdateWindow(windowHandle,
1058 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1059 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001060 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001061 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001062 }
1063 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001064 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001065}
1066
Garfield Tane84e6f92019-08-29 17:28:41 -07001067std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001068 int32_t displayId) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00001069 std::vector<TouchedMonitor> touchedMonitors;
1070
1071 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
1072 addGestureMonitors(monitors, touchedMonitors);
Michael Wright3dd60e22019-03-27 22:06:44 +00001073 return touchedMonitors;
1074}
1075
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001076void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001077 const char* reason;
1078 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001079 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001081 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001082#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001083 reason = "inbound event was dropped because the policy consumed it";
1084 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001085 case DropReason::DISABLED:
1086 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001087 ALOGI("Dropped event because input dispatch is disabled.");
1088 }
1089 reason = "inbound event was dropped because input dispatch is disabled";
1090 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001091 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001092 ALOGI("Dropped event because of pending overdue app switch.");
1093 reason = "inbound event was dropped because of pending overdue app switch";
1094 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001095 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001096 ALOGI("Dropped event because the current application is not responding and the user "
1097 "has started interacting with a different application.");
1098 reason = "inbound event was dropped because the current application is not responding "
1099 "and the user has started interacting with a different application";
1100 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001101 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001102 ALOGI("Dropped event because it is stale.");
1103 reason = "inbound event was dropped because it is stale";
1104 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001105 case DropReason::NO_POINTER_CAPTURE:
1106 ALOGI("Dropped event because there is no window with Pointer Capture.");
1107 reason = "inbound event was dropped because there is no window with Pointer Capture";
1108 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001109 case DropReason::NOT_DROPPED: {
1110 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001111 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001112 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001113 }
1114
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001115 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001116 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001117 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1118 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001119 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001120 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001121 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001122 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1123 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001124 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1125 synthesizeCancelationEventsForAllConnectionsLocked(options);
1126 } else {
1127 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1128 synthesizeCancelationEventsForAllConnectionsLocked(options);
1129 }
1130 break;
1131 }
Chris Yef59a2f42020-10-16 12:55:26 -07001132 case EventEntry::Type::SENSOR: {
1133 break;
1134 }
arthurhungb89ccb02020-12-30 16:19:01 +08001135 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1136 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001137 break;
1138 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001139 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001140 case EventEntry::Type::CONFIGURATION_CHANGED:
1141 case EventEntry::Type::DEVICE_RESET: {
Chris Yef59a2f42020-10-16 12:55:26 -07001142 LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001143 break;
1144 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001145 }
1146}
1147
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001148static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001149 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1150 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001151}
1152
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001153bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1154 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1155 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1156 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001157}
1158
1159bool InputDispatcher::isAppSwitchPendingLocked() {
1160 return mAppSwitchDueTime != LONG_LONG_MAX;
1161}
1162
1163void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1164 mAppSwitchDueTime = LONG_LONG_MAX;
1165
1166#if DEBUG_APP_SWITCH
1167 if (handled) {
1168 ALOGD("App switch has arrived.");
1169 } else {
1170 ALOGD("App switch was abandoned.");
1171 }
1172#endif
1173}
1174
Michael Wrightd02c5b62014-02-10 15:10:22 -08001175bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001176 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001177}
1178
Prabir Pradhancef936d2021-07-21 16:17:52 +00001179bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001180 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001181 return false;
1182 }
1183
1184 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001185 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001186 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001187 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1188 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001189 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001190 return true;
1191}
1192
Prabir Pradhancef936d2021-07-21 16:17:52 +00001193void InputDispatcher::postCommandLocked(Command&& command) {
1194 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001195}
1196
1197void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001198 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001199 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001200 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001201 releaseInboundEventLocked(entry);
1202 }
1203 traceInboundQueueLengthLocked();
1204}
1205
1206void InputDispatcher::releasePendingEventLocked() {
1207 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001208 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001209 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001210 }
1211}
1212
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001213void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001214 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001215 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001216#if DEBUG_DISPATCH_CYCLE
1217 ALOGD("Injected inbound event was dropped.");
1218#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001219 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001220 }
1221 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001222 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001223 }
1224 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001225}
1226
1227void InputDispatcher::resetKeyRepeatLocked() {
1228 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001229 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001230 }
1231}
1232
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001233std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1234 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001235
Michael Wright2e732952014-09-24 13:26:59 -07001236 uint32_t policyFlags = entry->policyFlags &
1237 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001238
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001239 std::shared_ptr<KeyEntry> newEntry =
1240 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1241 entry->source, entry->displayId, policyFlags, entry->action,
1242 entry->flags, entry->keyCode, entry->scanCode,
1243 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001244
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001245 newEntry->syntheticRepeat = true;
1246 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001247 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001248 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001249}
1250
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001251bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001252 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001253#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001254 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001255#endif
1256
1257 // Reset key repeating in case a keyboard device was added or removed or something.
1258 resetKeyRepeatLocked();
1259
1260 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001261 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1262 scoped_unlock unlock(mLock);
1263 mPolicy->notifyConfigurationChanged(eventTime);
1264 };
1265 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001266 return true;
1267}
1268
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001269bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1270 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001271#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001272 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1273 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001274#endif
1275
liushenxiang42232912021-05-21 20:24:09 +08001276 // Reset key repeating in case a keyboard device was disabled or enabled.
1277 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1278 resetKeyRepeatLocked();
1279 }
1280
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001281 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001282 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001283 synthesizeCancelationEventsForAllConnectionsLocked(options);
1284 return true;
1285}
1286
Vishnu Nairad321cd2020-08-20 16:40:21 -07001287void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001288 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001289 if (mPendingEvent != nullptr) {
1290 // Move the pending event to the front of the queue. This will give the chance
1291 // for the pending event to get dispatched to the newly focused window
1292 mInboundQueue.push_front(mPendingEvent);
1293 mPendingEvent = nullptr;
1294 }
1295
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001296 std::unique_ptr<FocusEntry> focusEntry =
1297 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1298 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001299
1300 // This event should go to the front of the queue, but behind all other focus events
1301 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001302 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001303 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001304 [](const std::shared_ptr<EventEntry>& event) {
1305 return event->type == EventEntry::Type::FOCUS;
1306 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001307
1308 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001309 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001310}
1311
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001312void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001313 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001314 if (channel == nullptr) {
1315 return; // Window has gone away
1316 }
1317 InputTarget target;
1318 target.inputChannel = channel;
1319 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1320 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001321 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1322 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001323 std::string reason = std::string("reason=").append(entry->reason);
1324 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001325 dispatchEventLocked(currentTime, entry, {target});
1326}
1327
Prabir Pradhan99987712020-11-10 18:43:05 -08001328void InputDispatcher::dispatchPointerCaptureChangedLocked(
1329 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1330 DropReason& dropReason) {
1331 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan167e6d92021-02-04 16:18:17 -08001332 if (entry->pointerCaptureEnabled && haveWindowWithPointerCapture) {
1333 LOG_ALWAYS_FATAL("Pointer Capture has already been enabled for the window.");
1334 }
1335 if (!entry->pointerCaptureEnabled && !haveWindowWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001336 // Pointer capture was already forcefully disabled because of focus change.
1337 dropReason = DropReason::NOT_DROPPED;
1338 return;
1339 }
1340
1341 // Set drop reason for early returns
1342 dropReason = DropReason::NO_POINTER_CAPTURE;
1343
1344 sp<IBinder> token;
1345 if (entry->pointerCaptureEnabled) {
1346 // Enable Pointer Capture
1347 if (!mFocusedWindowRequestedPointerCapture) {
1348 // This can happen if a window requests capture and immediately releases capture.
1349 ALOGW("No window requested Pointer Capture.");
1350 return;
1351 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08001352 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001353 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1354 mWindowTokenWithPointerCapture = token;
1355 } else {
1356 // Disable Pointer Capture
1357 token = mWindowTokenWithPointerCapture;
1358 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001359 if (mFocusedWindowRequestedPointerCapture) {
1360 mFocusedWindowRequestedPointerCapture = false;
1361 setPointerCaptureLocked(false);
1362 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001363 }
1364
1365 auto channel = getInputChannelLocked(token);
1366 if (channel == nullptr) {
1367 // Window has gone away, clean up Pointer Capture state.
1368 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001369 if (mFocusedWindowRequestedPointerCapture) {
1370 mFocusedWindowRequestedPointerCapture = false;
1371 setPointerCaptureLocked(false);
1372 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001373 return;
1374 }
1375 InputTarget target;
1376 target.inputChannel = channel;
1377 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1378 entry->dispatchInProgress = true;
1379 dispatchEventLocked(currentTime, entry, {target});
1380
1381 dropReason = DropReason::NOT_DROPPED;
1382}
1383
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001384bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001385 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001386 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001387 if (!entry->dispatchInProgress) {
1388 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1389 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1390 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1391 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001392 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001393 // We have seen two identical key downs in a row which indicates that the device
1394 // driver is automatically generating key repeats itself. We take note of the
1395 // repeat here, but we disable our own next key repeat timer since it is clear that
1396 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001397 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1398 // Make sure we don't get key down from a different device. If a different
1399 // device Id has same key pressed down, the new device Id will replace the
1400 // current one to hold the key repeat with repeat count reset.
1401 // In the future when got a KEY_UP on the device id, drop it and do not
1402 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001403 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1404 resetKeyRepeatLocked();
1405 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1406 } else {
1407 // Not a repeat. Save key down state in case we do see a repeat later.
1408 resetKeyRepeatLocked();
1409 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1410 }
1411 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001412 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1413 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001414 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001415#if DEBUG_INBOUND_EVENT_DETAILS
1416 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1417#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001418 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001419 resetKeyRepeatLocked();
1420 }
1421
1422 if (entry->repeatCount == 1) {
1423 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1424 } else {
1425 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1426 }
1427
1428 entry->dispatchInProgress = true;
1429
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001430 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001431 }
1432
1433 // Handle case where the policy asked us to try again later last time.
1434 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1435 if (currentTime < entry->interceptKeyWakeupTime) {
1436 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1437 *nextWakeupTime = entry->interceptKeyWakeupTime;
1438 }
1439 return false; // wait until next wakeup
1440 }
1441 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1442 entry->interceptKeyWakeupTime = 0;
1443 }
1444
1445 // Give the policy a chance to intercept the key.
1446 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1447 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001448 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001449 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001450
1451 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1452 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1453 };
1454 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001455 return false; // wait for the command to run
1456 } else {
1457 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1458 }
1459 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001460 if (*dropReason == DropReason::NOT_DROPPED) {
1461 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001462 }
1463 }
1464
1465 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001466 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001467 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001468 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1469 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001470 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001471 return true;
1472 }
1473
1474 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001475 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001476 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001477 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001478 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001479 return false;
1480 }
1481
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001482 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001483 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001484 return true;
1485 }
1486
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001487 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001488 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001489
1490 // Dispatch the key.
1491 dispatchEventLocked(currentTime, entry, inputTargets);
1492 return true;
1493}
1494
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001495void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001496#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001497 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001498 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1499 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001500 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1501 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1502 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001503#endif
1504}
1505
Prabir Pradhancef936d2021-07-21 16:17:52 +00001506void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1507 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001508 DropReason* dropReason, nsecs_t* nextWakeupTime) {
1509#if DEBUG_OUTBOUND_EVENT_DETAILS
1510 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1511 "source=0x%x, sensorType=%s",
1512 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Prabir Pradhanbe05b5b2021-02-24 16:39:43 -08001513 NamedEnum::string(entry->sensorType).c_str());
Chris Yef59a2f42020-10-16 12:55:26 -07001514#endif
Prabir Pradhancef936d2021-07-21 16:17:52 +00001515 auto command = [this, entry]() REQUIRES(mLock) {
1516 scoped_unlock unlock(mLock);
1517
1518 if (entry->accuracyChanged) {
1519 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1520 }
1521 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1522 entry->hwTimestamp, entry->values);
1523 };
1524 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001525}
1526
1527bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
1528#if DEBUG_OUTBOUND_EVENT_DETAILS
1529 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
1530 NamedEnum::string(sensorType).c_str());
1531#endif
1532 { // acquire lock
1533 std::scoped_lock _l(mLock);
1534
1535 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1536 std::shared_ptr<EventEntry> entry = *it;
1537 if (entry->type == EventEntry::Type::SENSOR) {
1538 it = mInboundQueue.erase(it);
1539 releaseInboundEventLocked(entry);
1540 }
1541 }
1542 }
1543 return true;
1544}
1545
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001546bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001547 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001548 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001549 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001550 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001551 entry->dispatchInProgress = true;
1552
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001553 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001554 }
1555
1556 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001557 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001558 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001559 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1560 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001561 return true;
1562 }
1563
1564 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1565
1566 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001567 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001568
1569 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001570 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001571 if (isPointerEvent) {
1572 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001573 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001574 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001575 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001576 } else {
1577 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001578 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001579 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001580 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001581 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001582 return false;
1583 }
1584
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001585 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001586 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001587 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1588 return true;
1589 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001590 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001591 CancelationOptions::Mode mode(isPointerEvent
1592 ? CancelationOptions::CANCEL_POINTER_EVENTS
1593 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1594 CancelationOptions options(mode, "input event injection failed");
1595 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001596 return true;
1597 }
1598
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001599 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001600 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001601
1602 // Dispatch the motion.
1603 if (conflictingPointerActions) {
1604 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001605 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001606 synthesizeCancelationEventsForAllConnectionsLocked(options);
1607 }
1608 dispatchEventLocked(currentTime, entry, inputTargets);
1609 return true;
1610}
1611
chaviw98318de2021-05-19 16:45:23 -05001612void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001613 bool isExiting, const MotionEntry& motionEntry) {
1614 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1615 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1616 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1617 PointerCoords pointerCoords;
1618 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1619 pointerCoords.transform(windowHandle->getInfo()->transform);
1620
1621 std::unique_ptr<DragEntry> dragEntry =
1622 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1623 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1624 pointerCoords.getY());
1625
1626 enqueueInboundEventLocked(std::move(dragEntry));
1627}
1628
1629void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1630 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1631 if (channel == nullptr) {
1632 return; // Window has gone away
1633 }
1634 InputTarget target;
1635 target.inputChannel = channel;
1636 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1637 entry->dispatchInProgress = true;
1638 dispatchEventLocked(currentTime, entry, {target});
1639}
1640
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001641void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001642#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001643 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001644 ", policyFlags=0x%x, "
1645 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1646 "metaState=0x%x, buttonState=0x%x,"
1647 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001648 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1649 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1650 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001651
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001652 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001653 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001654 "x=%f, y=%f, pressure=%f, size=%f, "
1655 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1656 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001657 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1658 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1659 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1660 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1661 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1662 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1663 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1664 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1665 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1666 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001667 }
1668#endif
1669}
1670
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001671void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1672 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001673 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001674 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001675#if DEBUG_DISPATCH_CYCLE
1676 ALOGD("dispatchEventToCurrentInputTargets");
1677#endif
1678
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001679 updateInteractionTokensLocked(*eventEntry, inputTargets);
1680
Michael Wrightd02c5b62014-02-10 15:10:22 -08001681 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1682
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001683 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001684
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001685 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001686 sp<Connection> connection =
1687 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001688 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001689 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001690 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001691 if (DEBUG_FOCUS) {
1692 ALOGD("Dropping event delivery to target with channel '%s' because it "
1693 "is no longer registered with the input dispatcher.",
1694 inputTarget.inputChannel->getName().c_str());
1695 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001696 }
1697 }
1698}
1699
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001700void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1701 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1702 // If the policy decides to close the app, we will get a channel removal event via
1703 // unregisterInputChannel, and will clean up the connection that way. We are already not
1704 // sending new pointers to the connection when it blocked, but focused events will continue to
1705 // pile up.
1706 ALOGW("Canceling events for %s because it is unresponsive",
1707 connection->inputChannel->getName().c_str());
1708 if (connection->status == Connection::STATUS_NORMAL) {
1709 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1710 "application not responding");
1711 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001712 }
1713}
1714
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001715void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001716 if (DEBUG_FOCUS) {
1717 ALOGD("Resetting ANR timeouts.");
1718 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001719
1720 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001721 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001722 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001723}
1724
Tiger Huang721e26f2018-07-24 22:26:19 +08001725/**
1726 * Get the display id that the given event should go to. If this event specifies a valid display id,
1727 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1728 * Focused display is the display that the user most recently interacted with.
1729 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001730int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001731 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001732 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001733 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001734 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1735 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001736 break;
1737 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001738 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001739 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1740 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001741 break;
1742 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001743 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001744 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001745 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001746 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001747 case EventEntry::Type::SENSOR:
1748 case EventEntry::Type::DRAG: {
Chris Yef59a2f42020-10-16 12:55:26 -07001749 ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001750 return ADISPLAY_ID_NONE;
1751 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001752 }
1753 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1754}
1755
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001756bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1757 const char* focusedWindowName) {
1758 if (mAnrTracker.empty()) {
1759 // already processed all events that we waited for
1760 mKeyIsWaitingForEventsTimeout = std::nullopt;
1761 return false;
1762 }
1763
1764 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1765 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001766 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001767 mKeyIsWaitingForEventsTimeout = currentTime +
1768 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1769 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001770 return true;
1771 }
1772
1773 // We still have pending events, and already started the timer
1774 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1775 return true; // Still waiting
1776 }
1777
1778 // Waited too long, and some connection still hasn't processed all motions
1779 // Just send the key to the focused window
1780 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1781 focusedWindowName);
1782 mKeyIsWaitingForEventsTimeout = std::nullopt;
1783 return false;
1784}
1785
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001786InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1787 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1788 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001789 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001790
Tiger Huang721e26f2018-07-24 22:26:19 +08001791 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001792 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001793 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001794 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1795
Michael Wrightd02c5b62014-02-10 15:10:22 -08001796 // If there is no currently focused window and no focused application
1797 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001798 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1799 ALOGI("Dropping %s event because there is no focused window or focused application in "
1800 "display %" PRId32 ".",
Chris Yef59a2f42020-10-16 12:55:26 -07001801 NamedEnum::string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001802 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001803 }
1804
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001805 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1806 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1807 // start interacting with another application via touch (app switch). This code can be removed
1808 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1809 // an app is expected to have a focused window.
1810 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1811 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1812 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001813 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1814 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1815 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001816 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001817 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001818 ALOGW("Waiting because no window has focus but %s may eventually add a "
1819 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001820 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001821 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001822 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001823 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1824 // Already raised ANR. Drop the event
1825 ALOGE("Dropping %s event because there is no focused window",
Chris Yef59a2f42020-10-16 12:55:26 -07001826 NamedEnum::string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001827 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001828 } else {
1829 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001830 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001831 }
1832 }
1833
1834 // we have a valid, non-null focused window
1835 resetNoFocusedWindowTimeoutLocked();
1836
Michael Wrightd02c5b62014-02-10 15:10:22 -08001837 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001838 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001839 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001840 }
1841
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001842 if (focusedWindowHandle->getInfo()->paused) {
1843 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001844 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001845 }
1846
1847 // If the event is a key event, then we must wait for all previous events to
1848 // complete before delivering it because previous events may have the
1849 // side-effect of transferring focus to a different window and we want to
1850 // ensure that the following keys are sent to the new window.
1851 //
1852 // Suppose the user touches a button in a window then immediately presses "A".
1853 // If the button causes a pop-up window to appear then we want to ensure that
1854 // the "A" key is delivered to the new pop-up window. This is because users
1855 // often anticipate pending UI changes when typing on a keyboard.
1856 // To obtain this behavior, we must serialize key events with respect to all
1857 // prior input events.
1858 if (entry.type == EventEntry::Type::KEY) {
1859 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1860 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001861 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001862 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001863 }
1864
1865 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001866 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001867 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1868 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001869
1870 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001871 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001872}
1873
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001874/**
1875 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1876 * that are currently unresponsive.
1877 */
1878std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1879 const std::vector<TouchedMonitor>& monitors) const {
1880 std::vector<TouchedMonitor> responsiveMonitors;
1881 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1882 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1883 sp<Connection> connection = getConnectionLocked(
1884 monitor.monitor.inputChannel->getConnectionToken());
1885 if (connection == nullptr) {
1886 ALOGE("Could not find connection for monitor %s",
1887 monitor.monitor.inputChannel->getName().c_str());
1888 return false;
1889 }
1890 if (!connection->responsive) {
1891 ALOGW("Unresponsive monitor %s will not get the new gesture",
1892 connection->inputChannel->getName().c_str());
1893 return false;
1894 }
1895 return true;
1896 });
1897 return responsiveMonitors;
1898}
1899
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001900InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1901 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1902 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001903 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001904 enum InjectionPermission {
1905 INJECTION_PERMISSION_UNKNOWN,
1906 INJECTION_PERMISSION_GRANTED,
1907 INJECTION_PERMISSION_DENIED
1908 };
1909
Michael Wrightd02c5b62014-02-10 15:10:22 -08001910 // For security reasons, we defer updating the touch state until we are sure that
1911 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001912 int32_t displayId = entry.displayId;
1913 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001914 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1915
1916 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001917 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001918 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05001919 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1920 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001921
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001922 // Copy current touch state into tempTouchState.
1923 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1924 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001925 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001926 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001927 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1928 mTouchStatesByDisplay.find(displayId);
1929 if (oldStateIt != mTouchStatesByDisplay.end()) {
1930 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001931 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001932 }
1933
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001934 bool isSplit = tempTouchState.split;
1935 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1936 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1937 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001938 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1939 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1940 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1941 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1942 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001943 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001944 bool wrongDevice = false;
1945 if (newGesture) {
1946 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001947 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001948 ALOGI("Dropping event because a pointer for a different device is already down "
1949 "in display %" PRId32,
1950 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001951 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001952 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001953 switchedDevice = false;
1954 wrongDevice = true;
1955 goto Failed;
1956 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001957 tempTouchState.reset();
1958 tempTouchState.down = down;
1959 tempTouchState.deviceId = entry.deviceId;
1960 tempTouchState.source = entry.source;
1961 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001962 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001963 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001964 ALOGI("Dropping move event because a pointer for a different device is already active "
1965 "in display %" PRId32,
1966 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001967 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001968 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001969 switchedDevice = false;
1970 wrongDevice = true;
1971 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001972 }
1973
1974 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1975 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1976
Garfield Tan00f511d2019-06-12 16:55:40 -07001977 int32_t x;
1978 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001979 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001980 // Always dispatch mouse events to cursor position.
1981 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001982 x = int32_t(entry.xCursorPosition);
1983 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001984 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001985 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1986 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001987 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001988 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001989 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1990 isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001991
1992 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001993 ? findTouchedGestureMonitorsLocked(displayId)
Michael Wright3dd60e22019-03-27 22:06:44 +00001994 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001995
Michael Wrightd02c5b62014-02-10 15:10:22 -08001996 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001997 if (newTouchedWindowHandle != nullptr &&
1998 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001999 // New window supports splitting, but we should never split mouse events.
2000 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002001 } else if (isSplit) {
2002 // New window does not support splitting but we have already split events.
2003 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002004 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002005 }
2006
2007 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002008 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002009 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002010 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002011 }
2012
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002013 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
2014 ALOGI("Not sending touch event to %s because it is paused",
2015 newTouchedWindowHandle->getName().c_str());
2016 newTouchedWindowHandle = nullptr;
2017 }
2018
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002019 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002020 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002021 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
2022 if (!isResponsive) {
2023 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002024 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
2025 newTouchedWindowHandle = nullptr;
2026 }
2027 }
2028
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002029 // Drop events that can't be trusted due to occlusion
2030 if (newTouchedWindowHandle != nullptr &&
2031 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2032 TouchOcclusionInfo occlusionInfo =
2033 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002034 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002035 if (DEBUG_TOUCH_OCCLUSION) {
2036 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2037 for (const auto& log : occlusionInfo.debugInfo) {
2038 ALOGD("%s", log.c_str());
2039 }
2040 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00002041 sendUntrustedTouchCommandLocked(occlusionInfo.obscuringPackage);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002042 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2043 ALOGW("Dropping untrusted touch event due to %s/%d",
2044 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2045 newTouchedWindowHandle = nullptr;
2046 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002047 }
2048 }
2049
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002050 // Also don't send the new touch event to unresponsive gesture monitors
2051 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
2052
Michael Wright3dd60e22019-03-27 22:06:44 +00002053 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
2054 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002055 "(%d, %d) in display %" PRId32 ".",
2056 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002057 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00002058 goto Failed;
2059 }
2060
2061 if (newTouchedWindowHandle != nullptr) {
2062 // Set target flags.
2063 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
2064 if (isSplit) {
2065 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002066 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002067 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2068 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2069 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2070 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2071 }
2072
2073 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07002074 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2075 newHoverWindowHandle = nullptr;
2076 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002077 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002078 }
2079
2080 // Update the temporary touch state.
2081 BitSet32 pointerIds;
2082 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002083 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002084 pointerIds.markBit(pointerId);
2085 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002086 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002087 }
2088
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002089 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002090 } else {
2091 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2092
2093 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002094 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002095 if (DEBUG_FOCUS) {
2096 ALOGD("Dropping event because the pointer is not down or we previously "
2097 "dropped the pointer down event in display %" PRId32,
2098 displayId);
2099 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002100 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002101 goto Failed;
2102 }
2103
arthurhung6d4bed92021-03-17 11:59:33 +08002104 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002105
Michael Wrightd02c5b62014-02-10 15:10:22 -08002106 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002107 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002108 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002109 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2110 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002111
chaviw98318de2021-05-19 16:45:23 -05002112 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002113 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002114 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002115 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2116 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002117 if (DEBUG_FOCUS) {
2118 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2119 oldTouchedWindowHandle->getName().c_str(),
2120 newTouchedWindowHandle->getName().c_str(), displayId);
2121 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002122 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002123 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2124 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2125 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002126
2127 // Make a slippery entrance into the new window.
2128 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2129 isSplit = true;
2130 }
2131
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002132 int32_t targetFlags =
2133 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002134 if (isSplit) {
2135 targetFlags |= InputTarget::FLAG_SPLIT;
2136 }
2137 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2138 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002139 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2140 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002141 }
2142
2143 BitSet32 pointerIds;
2144 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002145 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002146 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002147 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002148 }
2149 }
2150 }
2151
2152 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002153 // Let the previous window know that the hover sequence is over, unless we already did it
2154 // when dispatching it as is to newTouchedWindowHandle.
2155 if (mLastHoverWindowHandle != nullptr &&
2156 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2157 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002158#if DEBUG_HOVER
2159 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002160 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002161#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002162 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2163 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002164 }
2165
Garfield Tandf26e862020-07-01 20:18:19 -07002166 // Let the new window know that the hover sequence is starting, unless we already did it
2167 // when dispatching it as is to newTouchedWindowHandle.
2168 if (newHoverWindowHandle != nullptr &&
2169 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2170 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002171#if DEBUG_HOVER
2172 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002173 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002174#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002175 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2176 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2177 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002178 }
2179 }
2180
2181 // Check permission to inject into all touched foreground windows and ensure there
2182 // is at least one touched foreground window.
2183 {
2184 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002185 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002186 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2187 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002188 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002189 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002190 injectionPermission = INJECTION_PERMISSION_DENIED;
2191 goto Failed;
2192 }
2193 }
2194 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002195 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002196 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002197 ALOGI("Dropping event because there is no touched foreground window in display "
2198 "%" PRId32 " or gesture monitor to receive it.",
2199 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002200 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002201 goto Failed;
2202 }
2203
2204 // Permission granted to injection into all touched foreground windows.
2205 injectionPermission = INJECTION_PERMISSION_GRANTED;
2206 }
2207
2208 // Check whether windows listening for outside touches are owned by the same UID. If it is
2209 // set the policy flag that we will not reveal coordinate information to this window.
2210 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002211 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002212 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002213 if (foregroundWindowHandle) {
2214 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002215 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002216 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002217 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2218 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2219 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002220 InputTarget::FLAG_ZERO_COORDS,
2221 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002222 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002223 }
2224 }
2225 }
2226 }
2227
Michael Wrightd02c5b62014-02-10 15:10:22 -08002228 // If this is the first pointer going down and the touched window has a wallpaper
2229 // then also add the touched wallpaper windows so they are locked in for the duration
2230 // of the touch gesture.
2231 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2232 // engine only supports touch events. We would need to add a mechanism similar
2233 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2234 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002235 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002236 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002237 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
chaviw98318de2021-05-19 16:45:23 -05002238 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002239 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002240 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2241 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002242 if (info->displayId == displayId &&
chaviw98318de2021-05-19 16:45:23 -05002243 windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002244 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002245 .addOrUpdateWindow(windowHandle,
2246 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2247 InputTarget::
2248 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2249 InputTarget::FLAG_DISPATCH_AS_IS,
2250 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002251 }
2252 }
2253 }
2254 }
2255
2256 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002257 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002258
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002259 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002260 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002261 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002262 }
2263
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002264 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002265 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002266 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002267 }
2268
Michael Wrightd02c5b62014-02-10 15:10:22 -08002269 // Drop the outside or hover touch windows since we will not care about them
2270 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002271 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002272
2273Failed:
2274 // Check injection permission once and for all.
2275 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002276 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002277 injectionPermission = INJECTION_PERMISSION_GRANTED;
2278 } else {
2279 injectionPermission = INJECTION_PERMISSION_DENIED;
2280 }
2281 }
2282
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002283 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2284 return injectionResult;
2285 }
2286
Michael Wrightd02c5b62014-02-10 15:10:22 -08002287 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002288 if (!wrongDevice) {
2289 if (switchedDevice) {
2290 if (DEBUG_FOCUS) {
2291 ALOGD("Conflicting pointer actions: Switched to a different device.");
2292 }
2293 *outConflictingPointerActions = true;
2294 }
2295
2296 if (isHoverAction) {
2297 // Started hovering, therefore no longer down.
2298 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002299 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002300 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2301 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002302 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002303 *outConflictingPointerActions = true;
2304 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002305 tempTouchState.reset();
2306 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2307 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2308 tempTouchState.deviceId = entry.deviceId;
2309 tempTouchState.source = entry.source;
2310 tempTouchState.displayId = displayId;
2311 }
2312 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2313 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2314 // All pointers up or canceled.
2315 tempTouchState.reset();
2316 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2317 // First pointer went down.
2318 if (oldState && oldState->down) {
2319 if (DEBUG_FOCUS) {
2320 ALOGD("Conflicting pointer actions: Down received while already down.");
2321 }
2322 *outConflictingPointerActions = true;
2323 }
2324 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2325 // One pointer went up.
2326 if (isSplit) {
2327 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2328 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002329
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002330 for (size_t i = 0; i < tempTouchState.windows.size();) {
2331 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2332 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2333 touchedWindow.pointerIds.clearBit(pointerId);
2334 if (touchedWindow.pointerIds.isEmpty()) {
2335 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2336 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002337 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002338 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002339 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002340 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002341 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002342 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002343
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002344 // Save changes unless the action was scroll in which case the temporary touch
2345 // state was only valid for this one action.
2346 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2347 if (tempTouchState.displayId >= 0) {
2348 mTouchStatesByDisplay[displayId] = tempTouchState;
2349 } else {
2350 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002351 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002352 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002353
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002354 // Update hover state.
2355 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002356 }
2357
Michael Wrightd02c5b62014-02-10 15:10:22 -08002358 return injectionResult;
2359}
2360
arthurhung6d4bed92021-03-17 11:59:33 +08002361void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
chaviw98318de2021-05-19 16:45:23 -05002362 const sp<WindowInfoHandle> dropWindow =
arthurhung6d4bed92021-03-17 11:59:33 +08002363 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002364 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002365 if (dropWindow) {
2366 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002367 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002368 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002369 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002370 }
2371 mDragState.reset();
2372}
2373
2374void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2375 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002376 return;
2377 }
2378
arthurhung6d4bed92021-03-17 11:59:33 +08002379 if (!mDragState->isStartDrag) {
2380 mDragState->isStartDrag = true;
2381 mDragState->isStylusButtonDownAtStart =
2382 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2383 }
2384
arthurhungb89ccb02020-12-30 16:19:01 +08002385 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2386 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2387 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2388 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002389 // Handle the special case : stylus button no longer pressed.
2390 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2391 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2392 finishDragAndDrop(entry.displayId, x, y);
2393 return;
2394 }
2395
chaviw98318de2021-05-19 16:45:23 -05002396 const sp<WindowInfoHandle> hoverWindowHandle =
arthurhung6d4bed92021-03-17 11:59:33 +08002397 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002398 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002399 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002400 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2401 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2402 if (mDragState->dragHoverWindowHandle != nullptr) {
2403 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2404 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002405 }
arthurhung6d4bed92021-03-17 11:59:33 +08002406 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002407 }
2408 // enqueue drag location if needed.
2409 if (hoverWindowHandle != nullptr) {
2410 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2411 }
arthurhung6d4bed92021-03-17 11:59:33 +08002412 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2413 finishDragAndDrop(entry.displayId, x, y);
2414 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002415 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002416 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002417 }
2418}
2419
chaviw98318de2021-05-19 16:45:23 -05002420void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002421 int32_t targetFlags, BitSet32 pointerIds,
2422 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002423 std::vector<InputTarget>::iterator it =
2424 std::find_if(inputTargets.begin(), inputTargets.end(),
2425 [&windowHandle](const InputTarget& inputTarget) {
2426 return inputTarget.inputChannel->getConnectionToken() ==
2427 windowHandle->getToken();
2428 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002429
chaviw98318de2021-05-19 16:45:23 -05002430 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002431
2432 if (it == inputTargets.end()) {
2433 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002434 std::shared_ptr<InputChannel> inputChannel =
2435 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002436 if (inputChannel == nullptr) {
2437 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2438 return;
2439 }
2440 inputTarget.inputChannel = inputChannel;
2441 inputTarget.flags = targetFlags;
2442 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Evan Rosky09576692021-07-01 12:22:09 -07002443 inputTarget.displayOrientation = windowInfo->displayOrientation;
Evan Rosky84f07f02021-04-16 10:42:42 -07002444 inputTarget.displaySize =
Evan Rosky44edce92021-05-14 18:09:55 -07002445 int2(windowHandle->getInfo()->displayWidth, windowHandle->getInfo()->displayHeight);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002446 inputTargets.push_back(inputTarget);
2447 it = inputTargets.end() - 1;
2448 }
2449
2450 ALOG_ASSERT(it->flags == targetFlags);
2451 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2452
chaviw1ff3d1e2020-07-01 15:53:47 -07002453 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002454}
2455
Michael Wright3dd60e22019-03-27 22:06:44 +00002456void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002457 int32_t displayId, float xOffset,
2458 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002459 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2460 mGlobalMonitorsByDisplay.find(displayId);
2461
2462 if (it != mGlobalMonitorsByDisplay.end()) {
2463 const std::vector<Monitor>& monitors = it->second;
2464 for (const Monitor& monitor : monitors) {
2465 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002466 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002467 }
2468}
2469
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002470void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2471 float yOffset,
2472 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002473 InputTarget target;
2474 target.inputChannel = monitor.inputChannel;
2475 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002476 ui::Transform t;
2477 t.set(xOffset, yOffset);
2478 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002479 inputTargets.push_back(target);
2480}
2481
chaviw98318de2021-05-19 16:45:23 -05002482bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002483 const InjectionState* injectionState) {
2484 if (injectionState &&
2485 (windowHandle == nullptr ||
2486 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2487 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002488 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002489 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002490 "owned by uid %d",
2491 injectionState->injectorPid, injectionState->injectorUid,
2492 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002493 } else {
2494 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002495 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002496 }
2497 return false;
2498 }
2499 return true;
2500}
2501
Robert Carrc9bf1d32020-04-13 17:21:08 -07002502/**
2503 * Indicate whether one window handle should be considered as obscuring
2504 * another window handle. We only check a few preconditions. Actually
2505 * checking the bounds is left to the caller.
2506 */
chaviw98318de2021-05-19 16:45:23 -05002507static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2508 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002509 // Compare by token so cloned layers aren't counted
2510 if (haveSameToken(windowHandle, otherHandle)) {
2511 return false;
2512 }
2513 auto info = windowHandle->getInfo();
2514 auto otherInfo = otherHandle->getInfo();
2515 if (!otherInfo->visible) {
2516 return false;
chaviw98318de2021-05-19 16:45:23 -05002517 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002518 // Those act as if they were invisible, so we don't need to flag them.
2519 // We do want to potentially flag touchable windows even if they have 0
2520 // opacity, since they can consume touches and alter the effects of the
2521 // user interaction (eg. apps that rely on
2522 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2523 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2524 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002525 } else if (info->ownerUid == otherInfo->ownerUid) {
2526 // If ownerUid is the same we don't generate occlusion events as there
2527 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002528 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002529 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002530 return false;
2531 } else if (otherInfo->displayId != info->displayId) {
2532 return false;
2533 }
2534 return true;
2535}
2536
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002537/**
2538 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2539 * untrusted, one should check:
2540 *
2541 * 1. If result.hasBlockingOcclusion is true.
2542 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2543 * BLOCK_UNTRUSTED.
2544 *
2545 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2546 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2547 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2548 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2549 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2550 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2551 *
2552 * If neither of those is true, then it means the touch can be allowed.
2553 */
2554InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002555 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2556 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002557 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002558 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002559 TouchOcclusionInfo info;
2560 info.hasBlockingOcclusion = false;
2561 info.obscuringOpacity = 0;
2562 info.obscuringUid = -1;
2563 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002564 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002565 if (windowHandle == otherHandle) {
2566 break; // All future windows are below us. Exit early.
2567 }
chaviw98318de2021-05-19 16:45:23 -05002568 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002569 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2570 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002571 if (DEBUG_TOUCH_OCCLUSION) {
2572 info.debugInfo.push_back(
2573 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2574 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002575 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2576 // we perform the checks below to see if the touch can be propagated or not based on the
2577 // window's touch occlusion mode
2578 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2579 info.hasBlockingOcclusion = true;
2580 info.obscuringUid = otherInfo->ownerUid;
2581 info.obscuringPackage = otherInfo->packageName;
2582 break;
2583 }
2584 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2585 uint32_t uid = otherInfo->ownerUid;
2586 float opacity =
2587 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2588 // Given windows A and B:
2589 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2590 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2591 opacityByUid[uid] = opacity;
2592 if (opacity > info.obscuringOpacity) {
2593 info.obscuringOpacity = opacity;
2594 info.obscuringUid = uid;
2595 info.obscuringPackage = otherInfo->packageName;
2596 }
2597 }
2598 }
2599 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002600 if (DEBUG_TOUCH_OCCLUSION) {
2601 info.debugInfo.push_back(
2602 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2603 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002604 return info;
2605}
2606
chaviw98318de2021-05-19 16:45:23 -05002607std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002608 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002609 return StringPrintf(INDENT2
2610 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2611 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2612 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2613 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002614 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002615 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002616 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002617 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2618 info->frameTop, info->frameRight, info->frameBottom,
2619 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002620 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2621 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2622 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002623}
2624
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002625bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2626 if (occlusionInfo.hasBlockingOcclusion) {
2627 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2628 occlusionInfo.obscuringUid);
2629 return false;
2630 }
2631 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2632 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2633 "%.2f, maximum allowed = %.2f)",
2634 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2635 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2636 return false;
2637 }
2638 return true;
2639}
2640
chaviw98318de2021-05-19 16:45:23 -05002641bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002642 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002643 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002644 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2645 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002646 if (windowHandle == otherHandle) {
2647 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002648 }
chaviw98318de2021-05-19 16:45:23 -05002649 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002650 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002651 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002652 return true;
2653 }
2654 }
2655 return false;
2656}
2657
chaviw98318de2021-05-19 16:45:23 -05002658bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002659 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002660 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2661 const WindowInfo* windowInfo = windowHandle->getInfo();
2662 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002663 if (windowHandle == otherHandle) {
2664 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002665 }
chaviw98318de2021-05-19 16:45:23 -05002666 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002667 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002668 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002669 return true;
2670 }
2671 }
2672 return false;
2673}
2674
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002675std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002676 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002677 if (applicationHandle != nullptr) {
2678 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002679 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002680 } else {
2681 return applicationHandle->getName();
2682 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002683 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002684 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002685 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002686 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002687 }
2688}
2689
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002690void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002691 if (eventEntry.type == EventEntry::Type::FOCUS ||
arthurhungb89ccb02020-12-30 16:19:01 +08002692 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED ||
2693 eventEntry.type == EventEntry::Type::DRAG) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002694 // Focus or pointer capture changed events are passed to apps, but do not represent user
2695 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002696 return;
2697 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002698 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002699 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002700 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002701 const WindowInfo* info = focusedWindowHandle->getInfo();
2702 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002703#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002704 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002705#endif
2706 return;
2707 }
2708 }
2709
2710 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002711 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002712 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002713 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2714 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002715 return;
2716 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002717
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002718 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002719 eventType = USER_ACTIVITY_EVENT_TOUCH;
2720 }
2721 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002722 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002723 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002724 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2725 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002726 return;
2727 }
2728 eventType = USER_ACTIVITY_EVENT_BUTTON;
2729 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002730 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002731 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002732 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002733 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002734 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08002735 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2736 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002737 LOG_ALWAYS_FATAL("%s events are not user activity",
Chris Yef59a2f42020-10-16 12:55:26 -07002738 NamedEnum::string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002739 break;
2740 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002741 }
2742
Prabir Pradhancef936d2021-07-21 16:17:52 +00002743 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2744 REQUIRES(mLock) {
2745 scoped_unlock unlock(mLock);
2746 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2747 };
2748 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002749}
2750
2751void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002752 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002753 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002754 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002755 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002756 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002757 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002758 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002759 ATRACE_NAME(message.c_str());
2760 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002761#if DEBUG_DISPATCH_CYCLE
2762 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002763 "globalScaleFactor=%f, pointerIds=0x%x %s",
2764 connection->getInputChannelName().c_str(), inputTarget.flags,
2765 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2766 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002767#endif
2768
2769 // Skip this event if the connection status is not normal.
2770 // We don't want to enqueue additional outbound events if the connection is broken.
2771 if (connection->status != Connection::STATUS_NORMAL) {
2772#if DEBUG_DISPATCH_CYCLE
2773 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002774 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002775#endif
2776 return;
2777 }
2778
2779 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002780 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2781 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2782 "Entry type %s should not have FLAG_SPLIT",
Chris Yef59a2f42020-10-16 12:55:26 -07002783 NamedEnum::string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002784
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002785 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002786 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002787 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002788 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002789 if (!splitMotionEntry) {
2790 return; // split event was dropped
2791 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002792 if (DEBUG_FOCUS) {
2793 ALOGD("channel '%s' ~ Split motion event.",
2794 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002795 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002796 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002797 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2798 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002799 return;
2800 }
2801 }
2802
2803 // Not splitting. Enqueue dispatch entries for the event as is.
2804 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2805}
2806
2807void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002808 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002809 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002810 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002811 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002812 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002813 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002814 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002815 ATRACE_NAME(message.c_str());
2816 }
2817
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002818 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002819
2820 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002821 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002822 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002823 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002824 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002825 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002826 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002827 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002828 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002829 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002830 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002831 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002832 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002833
2834 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002835 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002836 startDispatchCycleLocked(currentTime, connection);
2837 }
2838}
2839
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002840void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002841 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002842 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002843 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002844 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002845 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2846 connection->getInputChannelName().c_str(),
2847 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002848 ATRACE_NAME(message.c_str());
2849 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002850 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002851 if (!(inputTargetFlags & dispatchMode)) {
2852 return;
2853 }
2854 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2855
2856 // This is a new event.
2857 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002858 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002859 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002860
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002861 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2862 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002863 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002864 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002865 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002866 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002867 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002868 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002869 dispatchEntry->resolvedAction = keyEntry.action;
2870 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002871
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002872 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2873 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002874#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002875 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2876 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002877#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002878 return; // skip the inconsistent event
2879 }
2880 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002881 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002882
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002883 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002884 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002885 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2886 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2887 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2888 static_cast<int32_t>(IdGenerator::Source::OTHER);
2889 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002890 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2891 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2892 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2893 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2894 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2895 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2896 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2897 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2898 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2899 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2900 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002901 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002902 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002903 }
2904 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002905 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2906 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002907#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002908 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2909 "event",
2910 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002911#endif
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00002912 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
2913 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002914 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2915 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002916
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002917 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002918 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2919 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2920 }
2921 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2922 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2923 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002925 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2926 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002927#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002928 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2929 "event",
2930 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002931#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002932 return; // skip the inconsistent event
2933 }
2934
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002935 dispatchEntry->resolvedEventId =
2936 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2937 ? mIdGenerator.nextId()
2938 : motionEntry.id;
2939 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2940 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2941 ") to MotionEvent(id=0x%" PRIx32 ").",
2942 motionEntry.id, dispatchEntry->resolvedEventId);
2943 ATRACE_NAME(message.c_str());
2944 }
2945
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08002946 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
2947 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
2948 // Skip reporting pointer down outside focus to the policy.
2949 break;
2950 }
2951
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002952 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002953 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002954
2955 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002956 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002957 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08002958 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2959 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002960 break;
2961 }
Chris Yef59a2f42020-10-16 12:55:26 -07002962 case EventEntry::Type::SENSOR: {
2963 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
2964 break;
2965 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002966 case EventEntry::Type::CONFIGURATION_CHANGED:
2967 case EventEntry::Type::DEVICE_RESET: {
2968 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chris Yef59a2f42020-10-16 12:55:26 -07002969 NamedEnum::string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002970 break;
2971 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002972 }
2973
2974 // Remember that we are waiting for this dispatch to complete.
2975 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002976 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002977 }
2978
2979 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002980 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00002981 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07002982}
2983
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002984/**
2985 * This function is purely for debugging. It helps us understand where the user interaction
2986 * was taking place. For example, if user is touching launcher, we will see a log that user
2987 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2988 * We will see both launcher and wallpaper in that list.
2989 * Once the interaction with a particular set of connections starts, no new logs will be printed
2990 * until the set of interacted connections changes.
2991 *
2992 * The following items are skipped, to reduce the logspam:
2993 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2994 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2995 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2996 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2997 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002998 */
2999void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3000 const std::vector<InputTarget>& targets) {
3001 // Skip ACTION_UP events, and all events other than keys and motions
3002 if (entry.type == EventEntry::Type::KEY) {
3003 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3004 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3005 return;
3006 }
3007 } else if (entry.type == EventEntry::Type::MOTION) {
3008 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3009 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3010 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3011 return;
3012 }
3013 } else {
3014 return; // Not a key or a motion
3015 }
3016
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003017 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003018 std::vector<sp<Connection>> newConnections;
3019 for (const InputTarget& target : targets) {
3020 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3021 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3022 continue; // Skip windows that receive ACTION_OUTSIDE
3023 }
3024
3025 sp<IBinder> token = target.inputChannel->getConnectionToken();
3026 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003027 if (connection == nullptr) {
3028 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003029 }
3030 newConnectionTokens.insert(std::move(token));
3031 newConnections.emplace_back(connection);
3032 }
3033 if (newConnectionTokens == mInteractionConnectionTokens) {
3034 return; // no change
3035 }
3036 mInteractionConnectionTokens = newConnectionTokens;
3037
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003038 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003039 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003040 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003041 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003042 std::string message = "Interaction with: " + targetList;
3043 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003044 message += "<none>";
3045 }
3046 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3047}
3048
chaviwfd6d3512019-03-25 13:23:49 -07003049void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003050 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003051 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003052 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3053 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003054 return;
3055 }
3056
Vishnu Nairc519ff72021-01-21 08:23:08 -08003057 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003058 if (focusedToken == token) {
3059 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003060 return;
3061 }
3062
Prabir Pradhancef936d2021-07-21 16:17:52 +00003063 auto command = [this, token]() REQUIRES(mLock) {
3064 scoped_unlock unlock(mLock);
3065 mPolicy->onPointerDownOutsideFocus(token);
3066 };
3067 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003068}
3069
3070void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003071 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003072 if (ATRACE_ENABLED()) {
3073 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003074 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003075 ATRACE_NAME(message.c_str());
3076 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003077#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003078 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003079#endif
3080
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003081 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3082 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003083 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003084 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003085 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003086 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003087
3088 // Publish the event.
3089 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003090 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3091 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003092 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003093 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3094 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003095
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003096 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003097 status = connection->inputPublisher
3098 .publishKeyEvent(dispatchEntry->seq,
3099 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3100 keyEntry.source, keyEntry.displayId,
3101 std::move(hmac), dispatchEntry->resolvedAction,
3102 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3103 keyEntry.scanCode, keyEntry.metaState,
3104 keyEntry.repeatCount, keyEntry.downTime,
3105 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003106 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003107 }
3108
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003109 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003110 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003111
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003112 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003113 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003114
chaviw82357092020-01-28 13:13:06 -08003115 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003116 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003117 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3118 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003119 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003120 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3121 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003122 // Don't apply window scale here since we don't want scale to affect raw
3123 // coordinates. The scale will be sent back to the client and applied
3124 // later when requesting relative coordinates.
3125 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3126 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003127 }
3128 usingCoords = scaledCoords;
3129 }
3130 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003131 // We don't want the dispatch target to know.
3132 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003133 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003134 scaledCoords[i].clear();
3135 }
3136 usingCoords = scaledCoords;
3137 }
3138 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003139
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003140 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003141
3142 // Publish the motion event.
3143 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003144 .publishMotionEvent(dispatchEntry->seq,
3145 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003146 motionEntry.deviceId, motionEntry.source,
3147 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003148 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003149 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003150 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003151 motionEntry.edgeFlags, motionEntry.metaState,
3152 motionEntry.buttonState,
3153 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003154 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003155 motionEntry.xPrecision, motionEntry.yPrecision,
3156 motionEntry.xCursorPosition,
3157 motionEntry.yCursorPosition,
Evan Rosky09576692021-07-01 12:22:09 -07003158 dispatchEntry->displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -07003159 dispatchEntry->displaySize.x,
3160 dispatchEntry->displaySize.y,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003161 motionEntry.downTime, motionEntry.eventTime,
3162 motionEntry.pointerCount,
3163 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003164 break;
3165 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003166
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003167 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003168 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003169 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003170 focusEntry.id,
3171 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003172 mInTouchMode);
3173 break;
3174 }
3175
Prabir Pradhan99987712020-11-10 18:43:05 -08003176 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3177 const auto& captureEntry =
3178 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3179 status = connection->inputPublisher
3180 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
3181 captureEntry.pointerCaptureEnabled);
3182 break;
3183 }
3184
arthurhungb89ccb02020-12-30 16:19:01 +08003185 case EventEntry::Type::DRAG: {
3186 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3187 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3188 dragEntry.id, dragEntry.x,
3189 dragEntry.y,
3190 dragEntry.isExiting);
3191 break;
3192 }
3193
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003194 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003195 case EventEntry::Type::DEVICE_RESET:
3196 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003197 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Chris Yef59a2f42020-10-16 12:55:26 -07003198 NamedEnum::string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003199 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003200 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003201 }
3202
3203 // Check the result.
3204 if (status) {
3205 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003206 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003207 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003208 "This is unexpected because the wait queue is empty, so the pipe "
3209 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003210 "event to it, status=%s(%d)",
3211 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3212 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003213 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3214 } else {
3215 // Pipe is full and we are waiting for the app to finish process some events
3216 // before sending more events to it.
3217#if DEBUG_DISPATCH_CYCLE
3218 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003219 "waiting for the application to catch up",
3220 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003221#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003222 }
3223 } else {
3224 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003225 "status=%s(%d)",
3226 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3227 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003228 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3229 }
3230 return;
3231 }
3232
3233 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003234 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3235 connection->outboundQueue.end(),
3236 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003237 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003238 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003239 if (connection->responsive) {
3240 mAnrTracker.insert(dispatchEntry->timeoutTime,
3241 connection->inputChannel->getConnectionToken());
3242 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003243 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003244 }
3245}
3246
chaviw09c8d2d2020-08-24 15:48:26 -07003247std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3248 size_t size;
3249 switch (event.type) {
3250 case VerifiedInputEvent::Type::KEY: {
3251 size = sizeof(VerifiedKeyEvent);
3252 break;
3253 }
3254 case VerifiedInputEvent::Type::MOTION: {
3255 size = sizeof(VerifiedMotionEvent);
3256 break;
3257 }
3258 }
3259 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3260 return mHmacKeyManager.sign(start, size);
3261}
3262
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003263const std::array<uint8_t, 32> InputDispatcher::getSignature(
3264 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3265 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3266 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3267 // Only sign events up and down events as the purely move events
3268 // are tied to their up/down counterparts so signing would be redundant.
3269 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3270 verifiedEvent.actionMasked = actionMasked;
3271 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003272 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003273 }
3274 return INVALID_HMAC;
3275}
3276
3277const std::array<uint8_t, 32> InputDispatcher::getSignature(
3278 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3279 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3280 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3281 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003282 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003283}
3284
Michael Wrightd02c5b62014-02-10 15:10:22 -08003285void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003286 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003287 bool handled, nsecs_t consumeTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003288#if DEBUG_DISPATCH_CYCLE
3289 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003290 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003291#endif
3292
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003293 if (connection->status == Connection::STATUS_BROKEN ||
3294 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003295 return;
3296 }
3297
3298 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003299 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3300 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3301 };
3302 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003303}
3304
3305void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003306 const sp<Connection>& connection,
3307 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003308#if DEBUG_DISPATCH_CYCLE
3309 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003310 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003311#endif
3312
3313 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003314 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003315 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003316 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003317 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318
3319 // The connection appears to be unrecoverably broken.
3320 // Ignore already broken or zombie connections.
3321 if (connection->status == Connection::STATUS_NORMAL) {
3322 connection->status = Connection::STATUS_BROKEN;
3323
3324 if (notify) {
3325 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003326 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3327 connection->getInputChannelName().c_str());
3328
3329 auto command = [this, connection]() REQUIRES(mLock) {
3330 if (connection->status == Connection::STATUS_ZOMBIE) return;
3331 scoped_unlock unlock(mLock);
3332 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3333 };
3334 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003335 }
3336 }
3337}
3338
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003339void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3340 while (!queue.empty()) {
3341 DispatchEntry* dispatchEntry = queue.front();
3342 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003343 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003344 }
3345}
3346
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003347void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003348 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003349 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003350 }
3351 delete dispatchEntry;
3352}
3353
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003354int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3355 std::scoped_lock _l(mLock);
3356 sp<Connection> connection = getConnectionLocked(connectionToken);
3357 if (connection == nullptr) {
3358 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3359 connectionToken.get(), events);
3360 return 0; // remove the callback
3361 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003362
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003363 bool notify;
3364 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3365 if (!(events & ALOOPER_EVENT_INPUT)) {
3366 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3367 "events=0x%x",
3368 connection->getInputChannelName().c_str(), events);
3369 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003370 }
3371
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003372 nsecs_t currentTime = now();
3373 bool gotOne = false;
3374 status_t status = OK;
3375 for (;;) {
3376 Result<InputPublisher::ConsumerResponse> result =
3377 connection->inputPublisher.receiveConsumerResponse();
3378 if (!result.ok()) {
3379 status = result.error().code();
3380 break;
3381 }
3382
3383 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3384 const InputPublisher::Finished& finish =
3385 std::get<InputPublisher::Finished>(*result);
3386 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3387 finish.consumeTime);
3388 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003389 if (shouldReportMetricsForConnection(*connection)) {
3390 const InputPublisher::Timeline& timeline =
3391 std::get<InputPublisher::Timeline>(*result);
3392 mLatencyTracker
3393 .trackGraphicsLatency(timeline.inputEventId,
3394 connection->inputChannel->getConnectionToken(),
3395 std::move(timeline.graphicsTimeline));
3396 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003397 }
3398 gotOne = true;
3399 }
3400 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003401 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003402 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003403 return 1;
3404 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003405 }
3406
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003407 notify = status != DEAD_OBJECT || !connection->monitor;
3408 if (notify) {
3409 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3410 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3411 status);
3412 }
3413 } else {
3414 // Monitor channels are never explicitly unregistered.
3415 // We do it automatically when the remote endpoint is closed so don't warn about them.
3416 const bool stillHaveWindowHandle =
3417 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3418 notify = !connection->monitor && stillHaveWindowHandle;
3419 if (notify) {
3420 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3421 connection->getInputChannelName().c_str(), events);
3422 }
3423 }
3424
3425 // Remove the channel.
3426 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3427 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003428}
3429
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003430void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003431 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003432 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003433 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003434 }
3435}
3436
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003437void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003438 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003439 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3440 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3441}
3442
3443void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3444 const CancelationOptions& options,
3445 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3446 for (const auto& it : monitorsByDisplay) {
3447 const std::vector<Monitor>& monitors = it.second;
3448 for (const Monitor& monitor : monitors) {
3449 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003450 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003451 }
3452}
3453
Michael Wrightd02c5b62014-02-10 15:10:22 -08003454void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003455 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003456 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003457 if (connection == nullptr) {
3458 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003459 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003460
3461 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003462}
3463
3464void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3465 const sp<Connection>& connection, const CancelationOptions& options) {
3466 if (connection->status == Connection::STATUS_BROKEN) {
3467 return;
3468 }
3469
3470 nsecs_t currentTime = now();
3471
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003472 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003473 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003474
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003475 if (cancelationEvents.empty()) {
3476 return;
3477 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003478#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003479 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3480 "with reality: %s, mode=%d.",
3481 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3482 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003483#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003484
3485 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003486 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003487 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3488 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003489 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003490 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003491 target.globalScaleFactor = windowInfo->globalScaleFactor;
3492 }
3493 target.inputChannel = connection->inputChannel;
3494 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3495
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003496 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003497 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003498 switch (cancelationEventEntry->type) {
3499 case EventEntry::Type::KEY: {
3500 logOutboundKeyDetails("cancel - ",
3501 static_cast<const KeyEntry&>(*cancelationEventEntry));
3502 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003503 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003504 case EventEntry::Type::MOTION: {
3505 logOutboundMotionDetails("cancel - ",
3506 static_cast<const MotionEntry&>(*cancelationEventEntry));
3507 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003508 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003509 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08003510 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3511 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003512 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Chris Yef59a2f42020-10-16 12:55:26 -07003513 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003514 break;
3515 }
3516 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003517 case EventEntry::Type::DEVICE_RESET:
3518 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003519 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003520 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003521 break;
3522 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003523 }
3524
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003525 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3526 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003527 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003528
3529 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003530}
3531
Svet Ganov5d3bc372020-01-26 23:11:07 -08003532void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3533 const sp<Connection>& connection) {
3534 if (connection->status == Connection::STATUS_BROKEN) {
3535 return;
3536 }
3537
3538 nsecs_t currentTime = now();
3539
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003540 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003541 connection->inputState.synthesizePointerDownEvents(currentTime);
3542
3543 if (downEvents.empty()) {
3544 return;
3545 }
3546
3547#if DEBUG_OUTBOUND_EVENT_DETAILS
3548 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3549 connection->getInputChannelName().c_str(), downEvents.size());
3550#endif
3551
3552 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003553 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003554 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3555 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003556 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003557 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003558 target.globalScaleFactor = windowInfo->globalScaleFactor;
3559 }
3560 target.inputChannel = connection->inputChannel;
3561 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3562
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003563 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003564 switch (downEventEntry->type) {
3565 case EventEntry::Type::MOTION: {
3566 logOutboundMotionDetails("down - ",
3567 static_cast<const MotionEntry&>(*downEventEntry));
3568 break;
3569 }
3570
3571 case EventEntry::Type::KEY:
3572 case EventEntry::Type::FOCUS:
3573 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003574 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003575 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003576 case EventEntry::Type::SENSOR:
3577 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003578 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003579 NamedEnum::string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003580 break;
3581 }
3582 }
3583
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003584 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3585 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003586 }
3587
3588 startDispatchCycleLocked(currentTime, connection);
3589}
3590
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003591std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3592 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003593 ALOG_ASSERT(pointerIds.value != 0);
3594
3595 uint32_t splitPointerIndexMap[MAX_POINTERS];
3596 PointerProperties splitPointerProperties[MAX_POINTERS];
3597 PointerCoords splitPointerCoords[MAX_POINTERS];
3598
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003599 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003600 uint32_t splitPointerCount = 0;
3601
3602 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003603 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003604 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003605 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003606 uint32_t pointerId = uint32_t(pointerProperties.id);
3607 if (pointerIds.hasBit(pointerId)) {
3608 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3609 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3610 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003611 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003612 splitPointerCount += 1;
3613 }
3614 }
3615
3616 if (splitPointerCount != pointerIds.count()) {
3617 // This is bad. We are missing some of the pointers that we expected to deliver.
3618 // Most likely this indicates that we received an ACTION_MOVE events that has
3619 // different pointer ids than we expected based on the previous ACTION_DOWN
3620 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3621 // in this way.
3622 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003623 "we expected there to be %d pointers. This probably means we received "
3624 "a broken sequence of pointer ids from the input device.",
3625 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003626 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003627 }
3628
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003629 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003630 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003631 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3632 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003633 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3634 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003635 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003636 uint32_t pointerId = uint32_t(pointerProperties.id);
3637 if (pointerIds.hasBit(pointerId)) {
3638 if (pointerIds.count() == 1) {
3639 // The first/last pointer went down/up.
3640 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003641 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003642 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3643 ? AMOTION_EVENT_ACTION_CANCEL
3644 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003645 } else {
3646 // A secondary pointer went down/up.
3647 uint32_t splitPointerIndex = 0;
3648 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3649 splitPointerIndex += 1;
3650 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003651 action = maskedAction |
3652 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003653 }
3654 } else {
3655 // An unrelated pointer changed.
3656 action = AMOTION_EVENT_ACTION_MOVE;
3657 }
3658 }
3659
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003660 int32_t newId = mIdGenerator.nextId();
3661 if (ATRACE_ENABLED()) {
3662 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3663 ") to MotionEvent(id=0x%" PRIx32 ").",
3664 originalMotionEntry.id, newId);
3665 ATRACE_NAME(message.c_str());
3666 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003667 std::unique_ptr<MotionEntry> splitMotionEntry =
3668 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3669 originalMotionEntry.deviceId, originalMotionEntry.source,
3670 originalMotionEntry.displayId,
3671 originalMotionEntry.policyFlags, action,
3672 originalMotionEntry.actionButton,
3673 originalMotionEntry.flags, originalMotionEntry.metaState,
3674 originalMotionEntry.buttonState,
3675 originalMotionEntry.classification,
3676 originalMotionEntry.edgeFlags,
3677 originalMotionEntry.xPrecision,
3678 originalMotionEntry.yPrecision,
3679 originalMotionEntry.xCursorPosition,
3680 originalMotionEntry.yCursorPosition,
3681 originalMotionEntry.downTime, splitPointerCount,
3682 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003683
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003684 if (originalMotionEntry.injectionState) {
3685 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003686 splitMotionEntry->injectionState->refCount += 1;
3687 }
3688
3689 return splitMotionEntry;
3690}
3691
3692void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3693#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003694 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003695#endif
3696
3697 bool needWake;
3698 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003699 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003700
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003701 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3702 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3703 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003704 } // release lock
3705
3706 if (needWake) {
3707 mLooper->wake();
3708 }
3709}
3710
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003711/**
3712 * If one of the meta shortcuts is detected, process them here:
3713 * Meta + Backspace -> generate BACK
3714 * Meta + Enter -> generate HOME
3715 * This will potentially overwrite keyCode and metaState.
3716 */
3717void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003718 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003719 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3720 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3721 if (keyCode == AKEYCODE_DEL) {
3722 newKeyCode = AKEYCODE_BACK;
3723 } else if (keyCode == AKEYCODE_ENTER) {
3724 newKeyCode = AKEYCODE_HOME;
3725 }
3726 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003727 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003728 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003729 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003730 keyCode = newKeyCode;
3731 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3732 }
3733 } else if (action == AKEY_EVENT_ACTION_UP) {
3734 // In order to maintain a consistent stream of up and down events, check to see if the key
3735 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3736 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003737 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003738 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003739 auto replacementIt = mReplacedKeys.find(replacement);
3740 if (replacementIt != mReplacedKeys.end()) {
3741 keyCode = replacementIt->second;
3742 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003743 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3744 }
3745 }
3746}
3747
Michael Wrightd02c5b62014-02-10 15:10:22 -08003748void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3749#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003750 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3751 "policyFlags=0x%x, action=0x%x, "
3752 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3753 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3754 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3755 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003756#endif
3757 if (!validateKeyEvent(args->action)) {
3758 return;
3759 }
3760
3761 uint32_t policyFlags = args->policyFlags;
3762 int32_t flags = args->flags;
3763 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003764 // InputDispatcher tracks and generates key repeats on behalf of
3765 // whatever notifies it, so repeatCount should always be set to 0
3766 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003767 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3768 policyFlags |= POLICY_FLAG_VIRTUAL;
3769 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3770 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003771 if (policyFlags & POLICY_FLAG_FUNCTION) {
3772 metaState |= AMETA_FUNCTION_ON;
3773 }
3774
3775 policyFlags |= POLICY_FLAG_TRUSTED;
3776
Michael Wright78f24442014-08-06 15:55:28 -07003777 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003778 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003779
Michael Wrightd02c5b62014-02-10 15:10:22 -08003780 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003781 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003782 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3783 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003784
Michael Wright2b3c3302018-03-02 17:19:13 +00003785 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003786 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003787 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3788 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003789 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003790 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003791
Michael Wrightd02c5b62014-02-10 15:10:22 -08003792 bool needWake;
3793 { // acquire lock
3794 mLock.lock();
3795
3796 if (shouldSendKeyToInputFilterLocked(args)) {
3797 mLock.unlock();
3798
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003799 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003800 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3801 return; // event was consumed by the filter
3802 }
3803
3804 mLock.lock();
3805 }
3806
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003807 std::unique_ptr<KeyEntry> newEntry =
3808 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3809 args->displayId, policyFlags, args->action, flags,
3810 keyCode, args->scanCode, metaState, repeatCount,
3811 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003812
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003813 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003814 mLock.unlock();
3815 } // release lock
3816
3817 if (needWake) {
3818 mLooper->wake();
3819 }
3820}
3821
3822bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3823 return mInputFilterEnabled;
3824}
3825
3826void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3827#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003828 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3829 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003830 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3831 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003832 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003833 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3834 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3835 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3836 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003837 for (uint32_t i = 0; i < args->pointerCount; i++) {
3838 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003839 "x=%f, y=%f, pressure=%f, size=%f, "
3840 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3841 "orientation=%f",
3842 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3843 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3844 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3845 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3846 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3847 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3848 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3849 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3850 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3851 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003852 }
3853#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003854 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3855 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003856 return;
3857 }
3858
3859 uint32_t policyFlags = args->policyFlags;
3860 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003861
3862 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003863 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003864 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3865 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003866 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003867 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003868
3869 bool needWake;
3870 { // acquire lock
3871 mLock.lock();
3872
3873 if (shouldSendMotionToInputFilterLocked(args)) {
3874 mLock.unlock();
3875
3876 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003877 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003878 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3879 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003880 args->metaState, args->buttonState, args->classification, transform,
3881 args->xPrecision, args->yPrecision, args->xCursorPosition,
Evan Rosky09576692021-07-01 12:22:09 -07003882 args->yCursorPosition, ui::Transform::ROT_0, INVALID_DISPLAY_SIZE,
3883 INVALID_DISPLAY_SIZE, args->downTime, args->eventTime,
3884 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003885
3886 policyFlags |= POLICY_FLAG_FILTERED;
3887 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3888 return; // event was consumed by the filter
3889 }
3890
3891 mLock.lock();
3892 }
3893
3894 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003895 std::unique_ptr<MotionEntry> newEntry =
3896 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3897 args->source, args->displayId, policyFlags,
3898 args->action, args->actionButton, args->flags,
3899 args->metaState, args->buttonState,
3900 args->classification, args->edgeFlags,
3901 args->xPrecision, args->yPrecision,
3902 args->xCursorPosition, args->yCursorPosition,
3903 args->downTime, args->pointerCount,
3904 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003905
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00003906 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
3907 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
3908 !mInputFilterEnabled) {
3909 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
3910 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
3911 }
3912
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003913 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003914 mLock.unlock();
3915 } // release lock
3916
3917 if (needWake) {
3918 mLooper->wake();
3919 }
3920}
3921
Chris Yef59a2f42020-10-16 12:55:26 -07003922void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
3923#if DEBUG_INBOUND_EVENT_DETAILS
3924 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3925 " sensorType=%s",
3926 args->id, args->eventTime, args->deviceId, args->source,
3927 NamedEnum::string(args->sensorType).c_str());
3928#endif
3929
3930 bool needWake;
3931 { // acquire lock
3932 mLock.lock();
3933
3934 // Just enqueue a new sensor event.
3935 std::unique_ptr<SensorEntry> newEntry =
3936 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
3937 args->source, 0 /* policyFlags*/, args->hwTimestamp,
3938 args->sensorType, args->accuracy,
3939 args->accuracyChanged, args->values);
3940
3941 needWake = enqueueInboundEventLocked(std::move(newEntry));
3942 mLock.unlock();
3943 } // release lock
3944
3945 if (needWake) {
3946 mLooper->wake();
3947 }
3948}
3949
Chris Yefb552902021-02-03 17:18:37 -08003950void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
3951#if DEBUG_INBOUND_EVENT_DETAILS
3952 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
3953 args->deviceId, args->isOn);
3954#endif
3955 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
3956}
3957
Michael Wrightd02c5b62014-02-10 15:10:22 -08003958bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003959 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003960}
3961
3962void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3963#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003964 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003965 "switchMask=0x%08x",
3966 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003967#endif
3968
3969 uint32_t policyFlags = args->policyFlags;
3970 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003971 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003972}
3973
3974void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3975#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003976 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3977 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003978#endif
3979
3980 bool needWake;
3981 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003982 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003983
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003984 std::unique_ptr<DeviceResetEntry> newEntry =
3985 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3986 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003987 } // release lock
3988
3989 if (needWake) {
3990 mLooper->wake();
3991 }
3992}
3993
Prabir Pradhan7e186182020-11-10 13:56:45 -08003994void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3995#if DEBUG_INBOUND_EVENT_DETAILS
3996 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3997 args->enabled ? "true" : "false");
3998#endif
3999
Prabir Pradhan99987712020-11-10 18:43:05 -08004000 bool needWake;
4001 { // acquire lock
4002 std::scoped_lock _l(mLock);
4003 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
4004 args->enabled);
4005 needWake = enqueueInboundEventLocked(std::move(entry));
4006 } // release lock
4007
4008 if (needWake) {
4009 mLooper->wake();
4010 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004011}
4012
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004013InputEventInjectionResult InputDispatcher::injectInputEvent(
4014 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4015 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004016#if DEBUG_INBOUND_EVENT_DETAILS
4017 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004018 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4019 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004020#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004021 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004022
4023 policyFlags |= POLICY_FLAG_INJECTED;
4024 if (hasInjectionPermission(injectorPid, injectorUid)) {
4025 policyFlags |= POLICY_FLAG_TRUSTED;
4026 }
4027
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004028 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004029 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4030 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4031 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4032 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4033 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004034 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004035 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004036 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004037 }
4038
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004039 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004040 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004041 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004042 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4043 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004044 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004045 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004046 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004047
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004048 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004049 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4050 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4051 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004052 int32_t keyCode = incomingKey.getKeyCode();
4053 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004054 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004055 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004056 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004057 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004058 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4059 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4060 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004061
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004062 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4063 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004064 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004065
4066 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4067 android::base::Timer t;
4068 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4069 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4070 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4071 std::to_string(t.duration().count()).c_str());
4072 }
4073 }
4074
4075 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004076 std::unique_ptr<KeyEntry> injectedEntry =
4077 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004078 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004079 incomingKey.getDisplayId(), policyFlags, action,
4080 flags, keyCode, incomingKey.getScanCode(), metaState,
4081 incomingKey.getRepeatCount(),
4082 incomingKey.getDownTime());
4083 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004084 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004085 }
4086
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004087 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004088 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
4089 int32_t action = motionEvent.getAction();
4090 size_t pointerCount = motionEvent.getPointerCount();
4091 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
4092 int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004093 int32_t flags = motionEvent.getFlags();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004094 int32_t displayId = motionEvent.getDisplayId();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004095 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004096 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004097 }
4098
4099 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004100 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004101 android::base::Timer t;
4102 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4103 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4104 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4105 std::to_string(t.duration().count()).c_str());
4106 }
4107 }
4108
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004109 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4110 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4111 }
4112
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004113 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004114 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4115 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004116 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004117 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4118 resolvedDeviceId, motionEvent.getSource(),
4119 motionEvent.getDisplayId(), policyFlags, action,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004120 actionButton, flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004121 motionEvent.getButtonState(),
4122 motionEvent.getClassification(),
4123 motionEvent.getEdgeFlags(),
4124 motionEvent.getXPrecision(),
4125 motionEvent.getYPrecision(),
4126 motionEvent.getRawXCursorPosition(),
4127 motionEvent.getRawYCursorPosition(),
4128 motionEvent.getDownTime(), uint32_t(pointerCount),
4129 pointerProperties, samplePointerCoords,
4130 motionEvent.getXOffset(),
4131 motionEvent.getYOffset());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004132 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004133 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004134 sampleEventTimes += 1;
4135 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004136 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004137 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4138 resolvedDeviceId, motionEvent.getSource(),
4139 motionEvent.getDisplayId(), policyFlags,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004140 action, actionButton, flags,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004141 motionEvent.getMetaState(),
4142 motionEvent.getButtonState(),
4143 motionEvent.getClassification(),
4144 motionEvent.getEdgeFlags(),
4145 motionEvent.getXPrecision(),
4146 motionEvent.getYPrecision(),
4147 motionEvent.getRawXCursorPosition(),
4148 motionEvent.getRawYCursorPosition(),
4149 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004150 uint32_t(pointerCount), pointerProperties,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004151 samplePointerCoords, motionEvent.getXOffset(),
4152 motionEvent.getYOffset());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004153 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004154 }
4155 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004156 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004157
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004158 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004159 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004160 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004161 }
4162
4163 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004164 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004165 injectionState->injectionIsAsync = true;
4166 }
4167
4168 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004169 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004170
4171 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004172 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004173 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004174 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004175 }
4176
4177 mLock.unlock();
4178
4179 if (needWake) {
4180 mLooper->wake();
4181 }
4182
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004183 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004184 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004185 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004186
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004187 if (syncMode == InputEventInjectionSync::NONE) {
4188 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004189 } else {
4190 for (;;) {
4191 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004192 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004193 break;
4194 }
4195
4196 nsecs_t remainingTimeout = endTime - now();
4197 if (remainingTimeout <= 0) {
4198#if DEBUG_INJECTION
4199 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004200 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004201#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004202 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004203 break;
4204 }
4205
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004206 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004207 }
4208
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004209 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4210 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004211 while (injectionState->pendingForegroundDispatches != 0) {
4212#if DEBUG_INJECTION
4213 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004214 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004215#endif
4216 nsecs_t remainingTimeout = endTime - now();
4217 if (remainingTimeout <= 0) {
4218#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004219 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4220 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004221#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004222 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004223 break;
4224 }
4225
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004226 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004227 }
4228 }
4229 }
4230
4231 injectionState->release();
4232 } // release lock
4233
4234#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004235 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004236 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004237#endif
4238
4239 return injectionResult;
4240}
4241
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004242std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004243 std::array<uint8_t, 32> calculatedHmac;
4244 std::unique_ptr<VerifiedInputEvent> result;
4245 switch (event.getType()) {
4246 case AINPUT_EVENT_TYPE_KEY: {
4247 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4248 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4249 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004250 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004251 break;
4252 }
4253 case AINPUT_EVENT_TYPE_MOTION: {
4254 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4255 VerifiedMotionEvent verifiedMotionEvent =
4256 verifiedMotionEventFromMotionEvent(motionEvent);
4257 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004258 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004259 break;
4260 }
4261 default: {
4262 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4263 return nullptr;
4264 }
4265 }
4266 if (calculatedHmac == INVALID_HMAC) {
4267 return nullptr;
4268 }
4269 if (calculatedHmac != event.getHmac()) {
4270 return nullptr;
4271 }
4272 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004273}
4274
Michael Wrightd02c5b62014-02-10 15:10:22 -08004275bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004276 return injectorUid == 0 ||
4277 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004278}
4279
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004280void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004281 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004282 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004283 if (injectionState) {
4284#if DEBUG_INJECTION
4285 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004286 "injectorPid=%d, injectorUid=%d",
4287 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004288#endif
4289
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004290 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004291 // Log the outcome since the injector did not wait for the injection result.
4292 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004293 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004294 ALOGV("Asynchronous input event injection succeeded.");
4295 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004296 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004297 ALOGW("Asynchronous input event injection failed.");
4298 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004299 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004300 ALOGW("Asynchronous input event injection permission denied.");
4301 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004302 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004303 ALOGW("Asynchronous input event injection timed out.");
4304 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004305 case InputEventInjectionResult::PENDING:
4306 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4307 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004308 }
4309 }
4310
4311 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004312 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004313 }
4314}
4315
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004316void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4317 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004318 if (injectionState) {
4319 injectionState->pendingForegroundDispatches += 1;
4320 }
4321}
4322
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004323void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4324 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004325 if (injectionState) {
4326 injectionState->pendingForegroundDispatches -= 1;
4327
4328 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004329 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004330 }
4331 }
4332}
4333
chaviw98318de2021-05-19 16:45:23 -05004334const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004335 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004336 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004337 auto it = mWindowHandlesByDisplay.find(displayId);
4338 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004339}
4340
chaviw98318de2021-05-19 16:45:23 -05004341sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004342 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004343 if (windowHandleToken == nullptr) {
4344 return nullptr;
4345 }
4346
Arthur Hungb92218b2018-08-14 12:00:21 +08004347 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004348 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4349 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004350 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004351 return windowHandle;
4352 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004353 }
4354 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004355 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004356}
4357
chaviw98318de2021-05-19 16:45:23 -05004358sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4359 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004360 if (windowHandleToken == nullptr) {
4361 return nullptr;
4362 }
4363
chaviw98318de2021-05-19 16:45:23 -05004364 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004365 if (windowHandle->getToken() == windowHandleToken) {
4366 return windowHandle;
4367 }
4368 }
4369 return nullptr;
4370}
4371
chaviw98318de2021-05-19 16:45:23 -05004372sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4373 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004374 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004375 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4376 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004377 if (handle->getId() == windowHandle->getId() &&
4378 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004379 if (windowHandle->getInfo()->displayId != it.first) {
4380 ALOGE("Found window %s in display %" PRId32
4381 ", but it should belong to display %" PRId32,
4382 windowHandle->getName().c_str(), it.first,
4383 windowHandle->getInfo()->displayId);
4384 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004385 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004386 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004387 }
4388 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004389 return nullptr;
4390}
4391
chaviw98318de2021-05-19 16:45:23 -05004392sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004393 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4394 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004395}
4396
chaviw98318de2021-05-19 16:45:23 -05004397bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004398 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4399 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004400 windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004401 if (connection != nullptr && noInputChannel) {
4402 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4403 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4404 return false;
4405 }
4406
4407 if (connection == nullptr) {
4408 if (!noInputChannel) {
4409 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4410 }
4411 return false;
4412 }
4413 if (!connection->responsive) {
4414 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4415 return false;
4416 }
4417 return true;
4418}
4419
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004420std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4421 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004422 auto connectionIt = mConnectionsByToken.find(token);
4423 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004424 return nullptr;
4425 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004426 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004427}
4428
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004429void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004430 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4431 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004432 // Remove all handles on a display if there are no windows left.
4433 mWindowHandlesByDisplay.erase(displayId);
4434 return;
4435 }
4436
4437 // Since we compare the pointer of input window handles across window updates, we need
4438 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004439 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4440 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4441 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004442 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004443 }
4444
chaviw98318de2021-05-19 16:45:23 -05004445 std::vector<sp<WindowInfoHandle>> newHandles;
4446 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004447 if (!handle->updateInfo()) {
4448 // handle no longer valid
4449 continue;
4450 }
4451
chaviw98318de2021-05-19 16:45:23 -05004452 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004453 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004454 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004455 info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
4456 const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
4457 !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004458 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004459 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004460 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004461 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004462 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004463 }
4464
4465 if (info->displayId != displayId) {
4466 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4467 handle->getName().c_str(), displayId, info->displayId);
4468 continue;
4469 }
4470
Robert Carredd13602020-04-13 17:24:34 -07004471 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4472 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004473 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004474 oldHandle->updateFrom(handle);
4475 newHandles.push_back(oldHandle);
4476 } else {
4477 newHandles.push_back(handle);
4478 }
4479 }
4480
4481 // Insert or replace
4482 mWindowHandlesByDisplay[displayId] = newHandles;
4483}
4484
Arthur Hung72d8dc32020-03-28 00:48:39 +00004485void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004486 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004487 { // acquire lock
4488 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004489 for (const auto& [displayId, handles] : handlesPerDisplay) {
4490 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004491 }
4492 }
4493 // Wake up poll loop since it may need to make new input dispatching choices.
4494 mLooper->wake();
4495}
4496
Arthur Hungb92218b2018-08-14 12:00:21 +08004497/**
4498 * Called from InputManagerService, update window handle list by displayId that can receive input.
4499 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4500 * If set an empty list, remove all handles from the specific display.
4501 * For focused handle, check if need to change and send a cancel event to previous one.
4502 * For removed handle, check if need to send a cancel event if already in touch.
4503 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004504void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004505 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004506 if (DEBUG_FOCUS) {
4507 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004508 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004509 windowList += iwh->getName() + " ";
4510 }
4511 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4512 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004513
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004514 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
chaviw98318de2021-05-19 16:45:23 -05004515 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004516 const bool noInputWindow =
chaviw98318de2021-05-19 16:45:23 -05004517 window->getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004518 if (noInputWindow && window->getToken() != nullptr) {
4519 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4520 window->getName().c_str());
4521 window->releaseChannel();
4522 }
4523 }
4524
Arthur Hung72d8dc32020-03-28 00:48:39 +00004525 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004526 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004527
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004528 // Save the old windows' orientation by ID before it gets updated.
4529 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004530 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004531 oldWindowOrientations.emplace(handle->getId(),
4532 handle->getInfo()->transform.getOrientation());
4533 }
4534
chaviw98318de2021-05-19 16:45:23 -05004535 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004536
chaviw98318de2021-05-19 16:45:23 -05004537 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004538 if (mLastHoverWindowHandle &&
4539 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4540 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004541 mLastHoverWindowHandle = nullptr;
4542 }
4543
Vishnu Nairc519ff72021-01-21 08:23:08 -08004544 std::optional<FocusResolver::FocusChanges> changes =
4545 mFocusResolver.setInputWindows(displayId, windowHandles);
4546 if (changes) {
4547 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004548 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004549
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004550 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4551 mTouchStatesByDisplay.find(displayId);
4552 if (stateIt != mTouchStatesByDisplay.end()) {
4553 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004554 for (size_t i = 0; i < state.windows.size();) {
4555 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004556 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004557 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004558 ALOGD("Touched window was removed: %s in display %" PRId32,
4559 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004560 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004561 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004562 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4563 if (touchedInputChannel != nullptr) {
4564 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4565 "touched window was removed");
4566 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004567 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004568 state.windows.erase(state.windows.begin() + i);
4569 } else {
4570 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004571 }
4572 }
arthurhungb89ccb02020-12-30 16:19:01 +08004573
arthurhung6d4bed92021-03-17 11:59:33 +08004574 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004575 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004576 if (mDragState &&
4577 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004578 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004579 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004580 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004581 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004582
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004583 if (isPerWindowInputRotationEnabled()) {
4584 // Determine if the orientation of any of the input windows have changed, and cancel all
4585 // pointer events if necessary.
chaviw98318de2021-05-19 16:45:23 -05004586 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4587 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004588 if (newWindowHandle != nullptr &&
4589 newWindowHandle->getInfo()->transform.getOrientation() !=
4590 oldWindowOrientations[oldWindowHandle->getId()]) {
4591 std::shared_ptr<InputChannel> inputChannel =
4592 getInputChannelLocked(newWindowHandle->getToken());
4593 if (inputChannel != nullptr) {
4594 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4595 "touched window's orientation changed");
4596 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4597 }
4598 }
4599 }
4600 }
4601
Arthur Hung72d8dc32020-03-28 00:48:39 +00004602 // Release information for windows that are no longer present.
4603 // This ensures that unused input channels are released promptly.
4604 // Otherwise, they might stick around until the window handle is destroyed
4605 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004606 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004607 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004608 if (DEBUG_FOCUS) {
4609 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004610 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004611 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004612 // To avoid making too many calls into the compat framework, only
4613 // check for window flags when windows are going away.
4614 // TODO(b/157929241) : delete this. This is only needed temporarily
4615 // in order to gather some data about the flag usage
chaviw98318de2021-05-19 16:45:23 -05004616 if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004617 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4618 oldWindowHandle->getName().c_str());
4619 if (mCompatService != nullptr) {
4620 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4621 oldWindowHandle->getInfo()->ownerUid);
4622 }
4623 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004624 }
chaviw291d88a2019-02-14 10:33:58 -08004625 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004626}
4627
4628void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004629 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004630 if (DEBUG_FOCUS) {
4631 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4632 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4633 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004634 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004635 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004636 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004637 } // release lock
4638
4639 // Wake up poll loop since it may need to make new input dispatching choices.
4640 mLooper->wake();
4641}
4642
Vishnu Nair599f1412021-06-21 10:39:58 -07004643void InputDispatcher::setFocusedApplicationLocked(
4644 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4645 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4646 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4647
4648 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4649 return; // This application is already focused. No need to wake up or change anything.
4650 }
4651
4652 // Set the new application handle.
4653 if (inputApplicationHandle != nullptr) {
4654 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4655 } else {
4656 mFocusedApplicationHandlesByDisplay.erase(displayId);
4657 }
4658
4659 // No matter what the old focused application was, stop waiting on it because it is
4660 // no longer focused.
4661 resetNoFocusedWindowTimeoutLocked();
4662}
4663
Tiger Huang721e26f2018-07-24 22:26:19 +08004664/**
4665 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4666 * the display not specified.
4667 *
4668 * We track any unreleased events for each window. If a window loses the ability to receive the
4669 * released event, we will send a cancel event to it. So when the focused display is changed, we
4670 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4671 * display. The display-specified events won't be affected.
4672 */
4673void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004674 if (DEBUG_FOCUS) {
4675 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4676 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004677 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004678 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004679
4680 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004681 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004682 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004683 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004684 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004685 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004686 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004687 CancelationOptions
4688 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4689 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004690 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004691 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4692 }
4693 }
4694 mFocusedDisplayId = displayId;
4695
Chris Ye3c2d6f52020-08-09 10:39:48 -07004696 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004697 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004698 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004699
Vishnu Nairad321cd2020-08-20 16:40:21 -07004700 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004701 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004702 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004703 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004704 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004705 }
4706 }
4707 }
4708
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004709 if (DEBUG_FOCUS) {
4710 logDispatchStateLocked();
4711 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004712 } // release lock
4713
4714 // Wake up poll loop since it may need to make new input dispatching choices.
4715 mLooper->wake();
4716}
4717
Michael Wrightd02c5b62014-02-10 15:10:22 -08004718void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004719 if (DEBUG_FOCUS) {
4720 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4721 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004722
4723 bool changed;
4724 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004725 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004726
4727 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4728 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004729 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004730 }
4731
4732 if (mDispatchEnabled && !enabled) {
4733 resetAndDropEverythingLocked("dispatcher is being disabled");
4734 }
4735
4736 mDispatchEnabled = enabled;
4737 mDispatchFrozen = frozen;
4738 changed = true;
4739 } else {
4740 changed = false;
4741 }
4742
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004743 if (DEBUG_FOCUS) {
4744 logDispatchStateLocked();
4745 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004746 } // release lock
4747
4748 if (changed) {
4749 // Wake up poll loop since it may need to make new input dispatching choices.
4750 mLooper->wake();
4751 }
4752}
4753
4754void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004755 if (DEBUG_FOCUS) {
4756 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4757 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004758
4759 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004760 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004761
4762 if (mInputFilterEnabled == enabled) {
4763 return;
4764 }
4765
4766 mInputFilterEnabled = enabled;
4767 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4768 } // release lock
4769
4770 // Wake up poll loop since there might be work to do to drop everything.
4771 mLooper->wake();
4772}
4773
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004774void InputDispatcher::setInTouchMode(bool inTouchMode) {
4775 std::scoped_lock lock(mLock);
4776 mInTouchMode = inTouchMode;
4777}
4778
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004779void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4780 if (opacity < 0 || opacity > 1) {
4781 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4782 return;
4783 }
4784
4785 std::scoped_lock lock(mLock);
4786 mMaximumObscuringOpacityForTouch = opacity;
4787}
4788
4789void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4790 std::scoped_lock lock(mLock);
4791 mBlockUntrustedTouchesMode = mode;
4792}
4793
arthurhungb89ccb02020-12-30 16:19:01 +08004794bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4795 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004796 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004797 if (DEBUG_FOCUS) {
4798 ALOGD("Trivial transfer to same window.");
4799 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004800 return true;
4801 }
4802
Michael Wrightd02c5b62014-02-10 15:10:22 -08004803 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004804 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004805
chaviw98318de2021-05-19 16:45:23 -05004806 sp<WindowInfoHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4807 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004808 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004809 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004810 return false;
4811 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004812 if (DEBUG_FOCUS) {
4813 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4814 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4815 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004816 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004817 if (DEBUG_FOCUS) {
4818 ALOGD("Cannot transfer focus because windows are on different displays.");
4819 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004820 return false;
4821 }
4822
4823 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004824 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4825 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004826 for (size_t i = 0; i < state.windows.size(); i++) {
4827 const TouchedWindow& touchedWindow = state.windows[i];
4828 if (touchedWindow.windowHandle == fromWindowHandle) {
4829 int32_t oldTargetFlags = touchedWindow.targetFlags;
4830 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004831
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004832 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004833
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004834 int32_t newTargetFlags = oldTargetFlags &
4835 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4836 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004837 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004838
arthurhungb89ccb02020-12-30 16:19:01 +08004839 // Store the dragging window.
4840 if (isDragDrop) {
arthurhung6d4bed92021-03-17 11:59:33 +08004841 mDragState = std::make_unique<DragState>(toWindowHandle);
arthurhungb89ccb02020-12-30 16:19:01 +08004842 }
4843
Jeff Brownf086ddb2014-02-11 14:28:48 -08004844 found = true;
4845 goto Found;
4846 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004847 }
4848 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004849 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004850
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004851 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004852 if (DEBUG_FOCUS) {
4853 ALOGD("Focus transfer failed because from window did not have focus.");
4854 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004855 return false;
4856 }
4857
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004858 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4859 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004860 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004861 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004862 CancelationOptions
4863 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4864 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004865 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004866 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004867 }
4868
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004869 if (DEBUG_FOCUS) {
4870 logDispatchStateLocked();
4871 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004872 } // release lock
4873
4874 // Wake up poll loop since it may need to make new input dispatching choices.
4875 mLooper->wake();
4876 return true;
4877}
4878
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00004879// Binder call
4880bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
4881 sp<IBinder> fromToken;
4882 { // acquire lock
4883 std::scoped_lock _l(mLock);
4884
chaviw98318de2021-05-19 16:45:23 -05004885 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00004886 if (toWindowHandle == nullptr) {
4887 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
4888 return false;
4889 }
4890
4891 const int32_t displayId = toWindowHandle->getInfo()->displayId;
4892
4893 auto touchStateIt = mTouchStatesByDisplay.find(displayId);
4894 if (touchStateIt == mTouchStatesByDisplay.end()) {
4895 ALOGD("Could not transfer touch because the display %" PRId32 " is not being touched",
4896 displayId);
4897 return false;
4898 }
4899
4900 TouchState& state = touchStateIt->second;
4901 if (state.windows.size() != 1) {
4902 ALOGW("Cannot transfer touch state because there are %zu windows being touched",
4903 state.windows.size());
4904 return false;
4905 }
4906 const TouchedWindow& touchedWindow = state.windows[0];
4907 fromToken = touchedWindow.windowHandle->getToken();
4908 } // release lock
4909
4910 return transferTouchFocus(fromToken, destChannelToken);
4911}
4912
Michael Wrightd02c5b62014-02-10 15:10:22 -08004913void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004914 if (DEBUG_FOCUS) {
4915 ALOGD("Resetting and dropping all events (%s).", reason);
4916 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004917
4918 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4919 synthesizeCancelationEventsForAllConnectionsLocked(options);
4920
4921 resetKeyRepeatLocked();
4922 releasePendingEventLocked();
4923 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004924 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004926 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004927 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004928 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004929 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004930}
4931
4932void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004933 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004934 dumpDispatchStateLocked(dump);
4935
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004936 std::istringstream stream(dump);
4937 std::string line;
4938
4939 while (std::getline(stream, line, '\n')) {
4940 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004941 }
4942}
4943
Prabir Pradhan99987712020-11-10 18:43:05 -08004944std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4945 std::string dump;
4946
4947 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4948 toString(mFocusedWindowRequestedPointerCapture));
4949
4950 std::string windowName = "None";
4951 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05004952 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08004953 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4954 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4955 : "token has capture without window";
4956 }
4957 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4958
4959 return dump;
4960}
4961
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004962void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004963 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4964 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4965 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004966 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004967
Tiger Huang721e26f2018-07-24 22:26:19 +08004968 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4969 dump += StringPrintf(INDENT "FocusedApplications:\n");
4970 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4971 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004972 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004973 const std::chrono::duration timeout =
4974 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004975 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004976 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004977 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004978 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004979 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004980 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004981 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004982
Vishnu Nairc519ff72021-01-21 08:23:08 -08004983 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08004984 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004985
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004986 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004987 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004988 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4989 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004990 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004991 state.displayId, toString(state.down), toString(state.split),
4992 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004993 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004994 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004995 for (size_t i = 0; i < state.windows.size(); i++) {
4996 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004997 dump += StringPrintf(INDENT4
4998 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4999 i, touchedWindow.windowHandle->getName().c_str(),
5000 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005001 }
5002 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005003 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005004 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005005 }
5006 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005007 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005008 }
5009
arthurhung6d4bed92021-03-17 11:59:33 +08005010 if (mDragState) {
5011 dump += StringPrintf(INDENT "DragState:\n");
5012 mDragState->dump(dump, INDENT2);
5013 }
5014
Arthur Hungb92218b2018-08-14 12:00:21 +08005015 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005016 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05005017 const std::vector<sp<WindowInfoHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08005018 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005019 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005020 dump += INDENT2 "Windows:\n";
5021 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005022 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5023 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005024
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005025 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005026 "paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005027 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005028 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005029 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005030 "applicationInfo.name=%s, "
5031 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005032 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005033 i, windowInfo->name.c_str(), windowInfo->id,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005034 windowInfo->displayId, toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07005035 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005036 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005037 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01005038 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005039 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01005040 windowInfo->frameLeft, windowInfo->frameTop,
5041 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005042 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005043 windowInfo->applicationInfo.name.c_str(),
5044 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005045 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01005046 dump += StringPrintf(", inputFeatures=%s",
5047 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005048 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005049 "ms, trustedOverlay=%s, hasToken=%s, "
5050 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005051 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005052 millis(windowInfo->dispatchingTimeout),
5053 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005054 toString(windowInfo->token != nullptr),
5055 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005056 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005057 }
5058 } else {
5059 dump += INDENT2 "Windows: <none>\n";
5060 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005061 }
5062 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005063 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005064 }
5065
Michael Wright3dd60e22019-03-27 22:06:44 +00005066 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005067 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005068 const std::vector<Monitor>& monitors = it.second;
5069 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
5070 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005071 }
5072 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005073 const std::vector<Monitor>& monitors = it.second;
5074 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
5075 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005076 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005077 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00005078 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005079 }
5080
5081 nsecs_t currentTime = now();
5082
5083 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005084 if (!mRecentQueue.empty()) {
5085 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005086 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005087 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005088 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005089 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005090 }
5091 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005092 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005093 }
5094
5095 // Dump event currently being dispatched.
5096 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005097 dump += INDENT "PendingEvent:\n";
5098 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005099 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005100 dump += StringPrintf(", age=%" PRId64 "ms\n",
5101 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005102 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005103 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005104 }
5105
5106 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005107 if (!mInboundQueue.empty()) {
5108 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005109 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005110 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005111 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005112 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005113 }
5114 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005115 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005116 }
5117
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005118 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005119 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005120 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5121 const KeyReplacement& replacement = pair.first;
5122 int32_t newKeyCode = pair.second;
5123 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005124 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005125 }
5126 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005127 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005128 }
5129
Prabir Pradhancef936d2021-07-21 16:17:52 +00005130 if (!mCommandQueue.empty()) {
5131 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5132 } else {
5133 dump += INDENT "CommandQueue: <empty>\n";
5134 }
5135
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005136 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005137 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005138 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005139 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005140 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005141 connection->inputChannel->getFd().get(),
5142 connection->getInputChannelName().c_str(),
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005143 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005144 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005145
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005146 if (!connection->outboundQueue.empty()) {
5147 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5148 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005149 dump += dumpQueue(connection->outboundQueue, currentTime);
5150
Michael Wrightd02c5b62014-02-10 15:10:22 -08005151 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005152 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005153 }
5154
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005155 if (!connection->waitQueue.empty()) {
5156 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5157 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005158 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005159 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005160 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005161 }
5162 }
5163 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005164 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005165 }
5166
5167 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005168 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5169 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005170 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005171 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005172 }
5173
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005174 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005175 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5176 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5177 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005178 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005179 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005180}
5181
Michael Wright3dd60e22019-03-27 22:06:44 +00005182void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5183 const size_t numMonitors = monitors.size();
5184 for (size_t i = 0; i < numMonitors; i++) {
5185 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005186 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005187 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5188 dump += "\n";
5189 }
5190}
5191
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005192class LooperEventCallback : public LooperCallback {
5193public:
5194 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5195 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5196
5197private:
5198 std::function<int(int events)> mCallback;
5199};
5200
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005201Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Garfield Tan15601662020-09-22 15:32:38 -07005202#if DEBUG_CHANNEL_CREATION
5203 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005204#endif
5205
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005206 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005207 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005208 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005209
5210 if (result) {
5211 return base::Error(result) << "Failed to open input channel pair with name " << name;
5212 }
5213
Michael Wrightd02c5b62014-02-10 15:10:22 -08005214 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005215 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005216 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005217 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005218 sp<Connection> connection =
5219 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005220
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005221 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5222 ALOGE("Created a new connection, but the token %p is already known", token.get());
5223 }
5224 mConnectionsByToken.emplace(token, connection);
5225
5226 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5227 this, std::placeholders::_1, token);
5228
5229 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005230 } // release lock
5231
5232 // Wake the looper because some connections have changed.
5233 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005234 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005235}
5236
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005237Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5238 bool isGestureMonitor,
5239 const std::string& name,
5240 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005241 std::shared_ptr<InputChannel> serverChannel;
5242 std::unique_ptr<InputChannel> clientChannel;
5243 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5244 if (result) {
5245 return base::Error(result) << "Failed to open input channel pair with name " << name;
5246 }
5247
Michael Wright3dd60e22019-03-27 22:06:44 +00005248 { // acquire lock
5249 std::scoped_lock _l(mLock);
5250
5251 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005252 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5253 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005254 }
5255
Garfield Tan15601662020-09-22 15:32:38 -07005256 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005257 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005258 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005259
5260 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5261 ALOGE("Created a new connection, but the token %p is already known", token.get());
5262 }
5263 mConnectionsByToken.emplace(token, connection);
5264 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5265 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005266
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005267 auto& monitorsByDisplay =
5268 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005269 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005270
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005271 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Siarhei Vishniakouc961c742021-05-19 19:16:59 +00005272 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5273 displayId, toString(isGestureMonitor), pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005274 }
Garfield Tan15601662020-09-22 15:32:38 -07005275
Michael Wright3dd60e22019-03-27 22:06:44 +00005276 // Wake the looper because some connections have changed.
5277 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005278 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005279}
5280
Garfield Tan15601662020-09-22 15:32:38 -07005281status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005282 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005283 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005284
Garfield Tan15601662020-09-22 15:32:38 -07005285 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005286 if (status) {
5287 return status;
5288 }
5289 } // release lock
5290
5291 // Wake the poll loop because removing the connection may have changed the current
5292 // synchronization state.
5293 mLooper->wake();
5294 return OK;
5295}
5296
Garfield Tan15601662020-09-22 15:32:38 -07005297status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5298 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005299 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005300 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005301 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005302 return BAD_VALUE;
5303 }
5304
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005305 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005306
Michael Wrightd02c5b62014-02-10 15:10:22 -08005307 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005308 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005309 }
5310
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005311 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005312
5313 nsecs_t currentTime = now();
5314 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5315
5316 connection->status = Connection::STATUS_ZOMBIE;
5317 return OK;
5318}
5319
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005320void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5321 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5322 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005323}
5324
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005325void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005326 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005327 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005328 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005329 std::vector<Monitor>& monitors = it->second;
5330 const size_t numMonitors = monitors.size();
5331 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005332 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005333 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5334 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005335 monitors.erase(monitors.begin() + i);
5336 break;
5337 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005338 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005339 if (monitors.empty()) {
5340 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005341 } else {
5342 ++it;
5343 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005344 }
5345}
5346
Michael Wright3dd60e22019-03-27 22:06:44 +00005347status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5348 { // acquire lock
5349 std::scoped_lock _l(mLock);
5350 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5351
5352 if (!foundDisplayId) {
5353 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5354 return BAD_VALUE;
5355 }
5356 int32_t displayId = foundDisplayId.value();
5357
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005358 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5359 mTouchStatesByDisplay.find(displayId);
5360 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005361 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5362 return BAD_VALUE;
5363 }
5364
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005365 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005366 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005367 std::optional<int32_t> foundDeviceId;
5368 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005369 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005370 requestingChannel = touchedMonitor.monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005371 foundDeviceId = state.deviceId;
5372 }
5373 }
5374 if (!foundDeviceId || !state.down) {
5375 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005376 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005377 return BAD_VALUE;
5378 }
5379 int32_t deviceId = foundDeviceId.value();
5380
5381 // Send cancel events to all the input channels we're stealing from.
5382 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005383 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005384 options.deviceId = deviceId;
5385 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005386 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005387 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005388 std::shared_ptr<InputChannel> channel =
5389 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005390 if (channel != nullptr) {
5391 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005392 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005393 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005394 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005395 canceledWindows += "]";
5396 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5397 canceledWindows.c_str());
5398
Michael Wright3dd60e22019-03-27 22:06:44 +00005399 // Then clear the current touch state so we stop dispatching to them as well.
5400 state.filterNonMonitors();
5401 }
5402 return OK;
5403}
5404
Prabir Pradhan99987712020-11-10 18:43:05 -08005405void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5406 { // acquire lock
5407 std::scoped_lock _l(mLock);
5408 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005409 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005410 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5411 windowHandle != nullptr ? windowHandle->getName().c_str()
5412 : "token without window");
5413 }
5414
Vishnu Nairc519ff72021-01-21 08:23:08 -08005415 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005416 if (focusedToken != windowToken) {
5417 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5418 enabled ? "enable" : "disable");
5419 return;
5420 }
5421
5422 if (enabled == mFocusedWindowRequestedPointerCapture) {
5423 ALOGW("Ignoring request to %s Pointer Capture: "
5424 "window has %s requested pointer capture.",
5425 enabled ? "enable" : "disable", enabled ? "already" : "not");
5426 return;
5427 }
5428
5429 mFocusedWindowRequestedPointerCapture = enabled;
5430 setPointerCaptureLocked(enabled);
5431 } // release lock
5432
5433 // Wake the thread to process command entries.
5434 mLooper->wake();
5435}
5436
Michael Wright3dd60e22019-03-27 22:06:44 +00005437std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5438 const sp<IBinder>& token) {
5439 for (const auto& it : mGestureMonitorsByDisplay) {
5440 const std::vector<Monitor>& monitors = it.second;
5441 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005442 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005443 return it.first;
5444 }
5445 }
5446 }
5447 return std::nullopt;
5448}
5449
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005450std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5451 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5452 if (gesturePid.has_value()) {
5453 return gesturePid;
5454 }
5455 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5456}
5457
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005458sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005459 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005460 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005461 }
5462
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005463 for (const auto& [token, connection] : mConnectionsByToken) {
5464 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005465 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005466 }
5467 }
Robert Carr4e670e52018-08-15 13:26:12 -07005468
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005469 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005470}
5471
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005472std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5473 sp<Connection> connection = getConnectionLocked(connectionToken);
5474 if (connection == nullptr) {
5475 return "<nullptr>";
5476 }
5477 return connection->getInputChannelName();
5478}
5479
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005480void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005481 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005482 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005483}
5484
Prabir Pradhancef936d2021-07-21 16:17:52 +00005485void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5486 const sp<Connection>& connection, uint32_t seq,
5487 bool handled, nsecs_t consumeTime) {
5488 // Handle post-event policy actions.
5489 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5490 if (dispatchEntryIt == connection->waitQueue.end()) {
5491 return;
5492 }
5493 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5494 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5495 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5496 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5497 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5498 }
5499 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5500 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5501 connection->inputChannel->getConnectionToken(),
5502 dispatchEntry->deliveryTime, consumeTime, finishTime);
5503 }
5504
5505 bool restartEvent;
5506 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5507 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5508 restartEvent =
5509 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5510 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5511 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5512 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5513 handled);
5514 } else {
5515 restartEvent = false;
5516 }
5517
5518 // Dequeue the event and start the next cycle.
5519 // Because the lock might have been released, it is possible that the
5520 // contents of the wait queue to have been drained, so we need to double-check
5521 // a few things.
5522 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5523 if (dispatchEntryIt != connection->waitQueue.end()) {
5524 dispatchEntry = *dispatchEntryIt;
5525 connection->waitQueue.erase(dispatchEntryIt);
5526 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5527 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5528 if (!connection->responsive) {
5529 connection->responsive = isConnectionResponsive(*connection);
5530 if (connection->responsive) {
5531 // The connection was unresponsive, and now it's responsive.
5532 processConnectionResponsiveLocked(*connection);
5533 }
5534 }
5535 traceWaitQueueLength(*connection);
5536 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
5537 connection->outboundQueue.push_front(dispatchEntry);
5538 traceOutboundQueueLength(*connection);
5539 } else {
5540 releaseDispatchEntry(dispatchEntry);
5541 }
5542 }
5543
5544 // Start the next dispatch cycle for this connection.
5545 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005546}
5547
Prabir Pradhancef936d2021-07-21 16:17:52 +00005548void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5549 const sp<IBinder>& newToken) {
5550 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5551 scoped_unlock unlock(mLock);
5552 mPolicy->notifyFocusChanged(oldToken, newToken);
5553 };
5554 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005555}
5556
Prabir Pradhancef936d2021-07-21 16:17:52 +00005557void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5558 auto command = [this, token, x, y]() REQUIRES(mLock) {
5559 scoped_unlock unlock(mLock);
5560 mPolicy->notifyDropWindow(token, x, y);
5561 };
5562 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005563}
5564
Prabir Pradhancef936d2021-07-21 16:17:52 +00005565void InputDispatcher::sendUntrustedTouchCommandLocked(const std::string& obscuringPackage) {
5566 auto command = [this, obscuringPackage]() REQUIRES(mLock) {
5567 scoped_unlock unlock(mLock);
5568 mPolicy->notifyUntrustedTouch(obscuringPackage);
5569 };
5570 postCommandLocked(std::move(command));
arthurhungf452d0b2021-01-06 00:19:52 +08005571}
5572
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005573void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5574 if (connection == nullptr) {
5575 LOG_ALWAYS_FATAL("Caller must check for nullness");
5576 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005577 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5578 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005579 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005580 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005581 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005582 return;
5583 }
5584 /**
5585 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5586 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5587 * has changed. This could cause newer entries to time out before the already dispatched
5588 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5589 * processes the events linearly. So providing information about the oldest entry seems to be
5590 * most useful.
5591 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005592 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005593 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5594 std::string reason =
5595 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005596 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005597 ns2ms(currentWait),
5598 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005599 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005600 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005601
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005602 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5603
5604 // Stop waking up for events on this connection, it is already unresponsive
5605 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005606}
5607
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005608void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5609 std::string reason =
5610 StringPrintf("%s does not have a focused window", application->getName().c_str());
5611 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005612
Prabir Pradhancef936d2021-07-21 16:17:52 +00005613 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5614 scoped_unlock unlock(mLock);
5615 mPolicy->notifyNoFocusedWindowAnr(application);
5616 };
5617 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005618}
5619
chaviw98318de2021-05-19 16:45:23 -05005620void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005621 const std::string& reason) {
5622 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5623 updateLastAnrStateLocked(windowLabel, reason);
5624}
5625
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005626void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5627 const std::string& reason) {
5628 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005629 updateLastAnrStateLocked(windowLabel, reason);
5630}
5631
5632void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5633 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005634 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005635 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005636 struct tm tm;
5637 localtime_r(&t, &tm);
5638 char timestr[64];
5639 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005640 mLastAnrState.clear();
5641 mLastAnrState += INDENT "ANR:\n";
5642 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005643 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5644 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005645 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005646}
5647
Prabir Pradhancef936d2021-07-21 16:17:52 +00005648void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5649 KeyEntry& entry) {
5650 const KeyEvent event = createKeyEvent(entry);
5651 nsecs_t delay = 0;
5652 { // release lock
5653 scoped_unlock unlock(mLock);
5654 android::base::Timer t;
5655 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5656 entry.policyFlags);
5657 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5658 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5659 std::to_string(t.duration().count()).c_str());
5660 }
5661 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005662
5663 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005664 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005665 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005666 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005667 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005668 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5669 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005670 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005671}
5672
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005673void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005674 auto command = [this, pid, reason = std::move(reason)]() REQUIRES(mLock) {
5675 scoped_unlock unlock(mLock);
5676 mPolicy->notifyMonitorUnresponsive(pid, reason);
5677 };
5678 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005679}
5680
Prabir Pradhancef936d2021-07-21 16:17:52 +00005681void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005682 std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005683 auto command = [this, token, reason = std::move(reason)]() REQUIRES(mLock) {
5684 scoped_unlock unlock(mLock);
5685 mPolicy->notifyWindowUnresponsive(token, reason);
5686 };
5687 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005688}
5689
5690void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005691 auto command = [this, pid]() REQUIRES(mLock) {
5692 scoped_unlock unlock(mLock);
5693 mPolicy->notifyMonitorResponsive(pid);
5694 };
5695 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005696}
5697
Prabir Pradhancef936d2021-07-21 16:17:52 +00005698void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) {
5699 auto command = [this, connectionToken]() REQUIRES(mLock) {
5700 scoped_unlock unlock(mLock);
5701 mPolicy->notifyWindowResponsive(connectionToken);
5702 };
5703 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005704}
5705
5706/**
5707 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5708 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5709 * command entry to the command queue.
5710 */
5711void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5712 std::string reason) {
5713 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5714 if (connection.monitor) {
5715 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5716 reason.c_str());
5717 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5718 if (!pid.has_value()) {
5719 ALOGE("Could not find unresponsive monitor for connection %s",
5720 connection.inputChannel->getName().c_str());
5721 return;
5722 }
5723 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5724 return;
5725 }
5726 // If not a monitor, must be a window
5727 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5728 reason.c_str());
5729 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5730}
5731
5732/**
5733 * Tell the policy that a connection has become responsive so that it can stop ANR.
5734 */
5735void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5736 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5737 if (connection.monitor) {
5738 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5739 if (!pid.has_value()) {
5740 ALOGE("Could not find responsive monitor for connection %s",
5741 connection.inputChannel->getName().c_str());
5742 return;
5743 }
5744 sendMonitorResponsiveCommandLocked(pid.value());
5745 return;
5746 }
5747 // If not a monitor, must be a window
5748 sendWindowResponsiveCommandLocked(connectionToken);
5749}
5750
Prabir Pradhancef936d2021-07-21 16:17:52 +00005751bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005752 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005753 KeyEntry& keyEntry, bool handled) {
5754 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005755 if (!handled) {
5756 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005757 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005758 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005759 return false;
5760 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005761
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005762 // Get the fallback key state.
5763 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005764 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005765 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005766 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005767 connection->inputState.removeFallbackKey(originalKeyCode);
5768 }
5769
5770 if (handled || !dispatchEntry->hasForegroundTarget()) {
5771 // If the application handles the original key for which we previously
5772 // generated a fallback or if the window is not a foreground window,
5773 // then cancel the associated fallback key, if any.
5774 if (fallbackKeyCode != -1) {
5775 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005776#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005777 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005778 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005779 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005780#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005781 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005782 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005783
5784 mLock.unlock();
5785
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005786 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005787 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005788
5789 mLock.lock();
5790
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005791 // Cancel the fallback key.
5792 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005793 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005794 "application handled the original non-fallback key "
5795 "or is no longer a foreground target, "
5796 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005797 options.keyCode = fallbackKeyCode;
5798 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005799 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005800 connection->inputState.removeFallbackKey(originalKeyCode);
5801 }
5802 } else {
5803 // If the application did not handle a non-fallback key, first check
5804 // that we are in a good state to perform unhandled key event processing
5805 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005806 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005807 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005808#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005809 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005810 "since this is not an initial down. "
5811 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005812 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005813#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005814 return false;
5815 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005816
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005817 // Dispatch the unhandled key to the policy.
5818#if DEBUG_OUTBOUND_EVENT_DETAILS
5819 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005820 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005821 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005822#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005823 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005824
5825 mLock.unlock();
5826
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005827 bool fallback =
5828 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005829 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005830
5831 mLock.lock();
5832
5833 if (connection->status != Connection::STATUS_NORMAL) {
5834 connection->inputState.removeFallbackKey(originalKeyCode);
5835 return false;
5836 }
5837
5838 // Latch the fallback keycode for this key on an initial down.
5839 // The fallback keycode cannot change at any other point in the lifecycle.
5840 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005841 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005842 fallbackKeyCode = event.getKeyCode();
5843 } else {
5844 fallbackKeyCode = AKEYCODE_UNKNOWN;
5845 }
5846 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5847 }
5848
5849 ALOG_ASSERT(fallbackKeyCode != -1);
5850
5851 // Cancel the fallback key if the policy decides not to send it anymore.
5852 // We will continue to dispatch the key to the policy but we will no
5853 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005854 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5855 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005856#if DEBUG_OUTBOUND_EVENT_DETAILS
5857 if (fallback) {
5858 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005859 "as a fallback for %d, but on the DOWN it had requested "
5860 "to send %d instead. Fallback canceled.",
5861 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005862 } else {
5863 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005864 "but on the DOWN it had requested to send %d. "
5865 "Fallback canceled.",
5866 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005867 }
5868#endif
5869
5870 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5871 "canceling fallback, policy no longer desires it");
5872 options.keyCode = fallbackKeyCode;
5873 synthesizeCancelationEventsForConnectionLocked(connection, options);
5874
5875 fallback = false;
5876 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005877 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005878 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005879 }
5880 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005881
5882#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005883 {
5884 std::string msg;
5885 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5886 connection->inputState.getFallbackKeys();
5887 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005888 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005889 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005890 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005891 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005892 }
5893#endif
5894
5895 if (fallback) {
5896 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005897 keyEntry.eventTime = event.getEventTime();
5898 keyEntry.deviceId = event.getDeviceId();
5899 keyEntry.source = event.getSource();
5900 keyEntry.displayId = event.getDisplayId();
5901 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5902 keyEntry.keyCode = fallbackKeyCode;
5903 keyEntry.scanCode = event.getScanCode();
5904 keyEntry.metaState = event.getMetaState();
5905 keyEntry.repeatCount = event.getRepeatCount();
5906 keyEntry.downTime = event.getDownTime();
5907 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005908
5909#if DEBUG_OUTBOUND_EVENT_DETAILS
5910 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005911 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005912 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005913#endif
5914 return true; // restart the event
5915 } else {
5916#if DEBUG_OUTBOUND_EVENT_DETAILS
5917 ALOGD("Unhandled key event: No fallback key.");
5918#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005919
5920 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005921 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005922 }
5923 }
5924 return false;
5925}
5926
Prabir Pradhancef936d2021-07-21 16:17:52 +00005927bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005928 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005929 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005930 return false;
5931}
5932
Michael Wrightd02c5b62014-02-10 15:10:22 -08005933void InputDispatcher::traceInboundQueueLengthLocked() {
5934 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005935 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005936 }
5937}
5938
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005939void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005940 if (ATRACE_ENABLED()) {
5941 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005942 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
5943 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005944 }
5945}
5946
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005947void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005948 if (ATRACE_ENABLED()) {
5949 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005950 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
5951 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005952 }
5953}
5954
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005955void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005956 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005957
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005958 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005959 dumpDispatchStateLocked(dump);
5960
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005961 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005962 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005963 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005964 }
5965}
5966
5967void InputDispatcher::monitor() {
5968 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005969 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005970 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005971 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005972}
5973
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005974/**
5975 * Wake up the dispatcher and wait until it processes all events and commands.
5976 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5977 * this method can be safely called from any thread, as long as you've ensured that
5978 * the work you are interested in completing has already been queued.
5979 */
5980bool InputDispatcher::waitForIdle() {
5981 /**
5982 * Timeout should represent the longest possible time that a device might spend processing
5983 * events and commands.
5984 */
5985 constexpr std::chrono::duration TIMEOUT = 100ms;
5986 std::unique_lock lock(mLock);
5987 mLooper->wake();
5988 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5989 return result == std::cv_status::no_timeout;
5990}
5991
Vishnu Naire798b472020-07-23 13:52:21 -07005992/**
5993 * Sets focus to the window identified by the token. This must be called
5994 * after updating any input window handles.
5995 *
5996 * Params:
5997 * request.token - input channel token used to identify the window that should gain focus.
5998 * request.focusedToken - the token that the caller expects currently to be focused. If the
5999 * specified token does not match the currently focused window, this request will be dropped.
6000 * If the specified focused token matches the currently focused window, the call will succeed.
6001 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6002 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6003 * when requesting the focus change. This determines which request gets
6004 * precedence if there is a focus change request from another source such as pointer down.
6005 */
Vishnu Nair958da932020-08-21 17:12:37 -07006006void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6007 { // acquire lock
6008 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006009 std::optional<FocusResolver::FocusChanges> changes =
6010 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6011 if (changes) {
6012 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006013 }
6014 } // release lock
6015 // Wake up poll loop since it may need to make new input dispatching choices.
6016 mLooper->wake();
6017}
6018
Vishnu Nairc519ff72021-01-21 08:23:08 -08006019void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6020 if (changes.oldFocus) {
6021 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006022 if (focusedInputChannel) {
6023 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6024 "focus left window");
6025 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006026 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006027 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006028 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006029 if (changes.newFocus) {
6030 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006031 }
6032
Prabir Pradhan99987712020-11-10 18:43:05 -08006033 // If a window has pointer capture, then it must have focus. We need to ensure that this
6034 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6035 // If the window loses focus before it loses pointer capture, then the window can be in a state
6036 // where it has pointer capture but not focus, violating the contract. Therefore we must
6037 // dispatch the pointer capture event before the focus event. Since focus events are added to
6038 // the front of the queue (above), we add the pointer capture event to the front of the queue
6039 // after the focus events are added. This ensures the pointer capture event ends up at the
6040 // front.
6041 disablePointerCaptureForcedLocked();
6042
Vishnu Nairc519ff72021-01-21 08:23:08 -08006043 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006044 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006045 }
6046}
Vishnu Nair958da932020-08-21 17:12:37 -07006047
Prabir Pradhan99987712020-11-10 18:43:05 -08006048void InputDispatcher::disablePointerCaptureForcedLocked() {
6049 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
6050 return;
6051 }
6052
6053 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6054
6055 if (mFocusedWindowRequestedPointerCapture) {
6056 mFocusedWindowRequestedPointerCapture = false;
6057 setPointerCaptureLocked(false);
6058 }
6059
6060 if (!mWindowTokenWithPointerCapture) {
6061 // No need to send capture changes because no window has capture.
6062 return;
6063 }
6064
6065 if (mPendingEvent != nullptr) {
6066 // Move the pending event to the front of the queue. This will give the chance
6067 // for the pending event to be dropped if it is a captured event.
6068 mInboundQueue.push_front(mPendingEvent);
6069 mPendingEvent = nullptr;
6070 }
6071
6072 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
6073 false /* hasCapture */);
6074 mInboundQueue.push_front(std::move(entry));
6075}
6076
Prabir Pradhan99987712020-11-10 18:43:05 -08006077void InputDispatcher::setPointerCaptureLocked(bool enabled) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006078 auto command = [this, enabled]() REQUIRES(mLock) {
6079 scoped_unlock unlock(mLock);
6080 mPolicy->setPointerCapture(enabled);
6081 };
6082 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006083}
6084
Vishnu Nair599f1412021-06-21 10:39:58 -07006085void InputDispatcher::displayRemoved(int32_t displayId) {
6086 { // acquire lock
6087 std::scoped_lock _l(mLock);
6088 // Set an empty list to remove all handles from the specific display.
6089 setInputWindowsLocked(/* window handles */ {}, displayId);
6090 setFocusedApplicationLocked(displayId, nullptr);
6091 // Call focus resolver to clean up stale requests. This must be called after input windows
6092 // have been removed for the removed display.
6093 mFocusResolver.displayRemoved(displayId);
6094 } // release lock
6095
6096 // Wake up poll loop since it may need to make new input dispatching choices.
6097 mLooper->wake();
6098}
6099
Garfield Tane84e6f92019-08-29 17:28:41 -07006100} // namespace android::inputdispatcher