blob: f190f67a6c0833f30db530fd5aa41de37eacaf97 [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
Michael Wright2b3c3302018-03-02 17:19:13 +000022#include <android-base/chrono_utils.h>
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080023#include <android-base/properties.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080024#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050025#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070026#include <binder/Binder.h>
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100027#include <binder/IServiceManager.h>
28#include <com/android/internal/compat/IPlatformCompatNative.h>
Dominik Laskowski75788452021-02-09 18:51:25 -080029#include <ftl/enum.h>
chaviw15fab6f2021-06-07 14:15:52 -050030#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080031#include <input/InputDevice.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070032#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000033#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070034#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010035#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070036#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080037
Michael Wright44753b12020-07-08 13:48:11 +010038#include <cerrno>
39#include <cinttypes>
40#include <climits>
41#include <cstddef>
42#include <ctime>
43#include <queue>
44#include <sstream>
45
46#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070047#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010048
Michael Wrightd02c5b62014-02-10 15:10:22 -080049#define INDENT " "
50#define INDENT2 " "
51#define INDENT3 " "
52#define INDENT4 " "
53
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080054using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000055using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080056using android::base::StringPrintf;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -070057using android::gui::DisplayInfo;
chaviw98318de2021-05-19 16:45:23 -050058using android::gui::FocusRequest;
59using android::gui::TouchOcclusionMode;
60using android::gui::WindowInfo;
61using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080062using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100063using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080064using android::os::InputEventInjectionResult;
65using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100066using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080067
Garfield Tane84e6f92019-08-29 17:28:41 -070068namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080069
Prabir Pradhancef936d2021-07-21 16:17:52 +000070namespace {
71
Prabir Pradhan61a5d242021-07-26 16:41:09 +000072// Log detailed debug messages about each inbound event notification to the dispatcher.
73constexpr bool DEBUG_INBOUND_EVENT_DETAILS = false;
74
75// Log detailed debug messages about each outbound event processed by the dispatcher.
76constexpr bool DEBUG_OUTBOUND_EVENT_DETAILS = false;
77
78// Log debug messages about the dispatch cycle.
79constexpr bool DEBUG_DISPATCH_CYCLE = false;
80
81// Log debug messages about channel creation
82constexpr bool DEBUG_CHANNEL_CREATION = false;
83
84// Log debug messages about input event injection.
85constexpr bool DEBUG_INJECTION = false;
86
87// Log debug messages about input focus tracking.
88constexpr bool DEBUG_FOCUS = false;
89
Antonio Kantekf16f2832021-09-28 04:39:20 +000090// Log debug messages about touch mode event
91constexpr bool DEBUG_TOUCH_MODE = false;
92
Prabir Pradhan61a5d242021-07-26 16:41:09 +000093// Log debug messages about touch occlusion
Prabir Pradhan61a5d242021-07-26 16:41:09 +000094constexpr bool DEBUG_TOUCH_OCCLUSION = true;
95
96// Log debug messages about the app switch latency optimization.
97constexpr bool DEBUG_APP_SWITCH = false;
98
99// Log debug messages about hover events.
100constexpr bool DEBUG_HOVER = false;
101
Prabir Pradhancef936d2021-07-21 16:17:52 +0000102// Temporarily releases a held mutex for the lifetime of the instance.
103// Named to match std::scoped_lock
104class scoped_unlock {
105public:
106 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
107 ~scoped_unlock() { mMutex.lock(); }
108
109private:
110 std::mutex& mMutex;
111};
112
Michael Wrightd02c5b62014-02-10 15:10:22 -0800113// Default input dispatching timeout if there is no focused application or paused window
114// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -0800115const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
116 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
117 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800118
119// Amount of time to allow for all pending events to be processed when an app switch
120// key is on the way. This is used to preempt input dispatch and drop input events
121// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000122constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800123
124// Amount of time to allow for an event to be dispatched (measured since its eventTime)
125// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000126constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800127
Michael Wrightd02c5b62014-02-10 15:10:22 -0800128// 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 +0000129constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
130
131// Log a warning when an interception call takes longer than this to process.
132constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800133
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700134// Additional key latency in case a connection is still processing some motion events.
135// This will help with the case when a user touched a button that opens a new window,
136// and gives us the chance to dispatch the key to this new window.
137constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
138
Michael Wrightd02c5b62014-02-10 15:10:22 -0800139// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000140constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
141
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000142// Event log tags. See EventLogTags.logtags for reference
143constexpr int LOGTAG_INPUT_INTERACTION = 62000;
144constexpr int LOGTAG_INPUT_FOCUS = 62001;
Arthur Hungb3307ee2021-10-14 10:57:37 +0000145constexpr int LOGTAG_INPUT_CANCEL = 62003;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000146
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000147inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800148 return systemTime(SYSTEM_TIME_MONOTONIC);
149}
150
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000151inline const char* toString(bool value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800152 return value ? "true" : "false";
153}
154
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000155inline const std::string toString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000156 if (binder == nullptr) {
157 return "<null>";
158 }
159 return StringPrintf("%p", binder.get());
160}
161
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000162inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700163 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
164 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800165}
166
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000167bool isValidKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800168 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700169 case AKEY_EVENT_ACTION_DOWN:
170 case AKEY_EVENT_ACTION_UP:
171 return true;
172 default:
173 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800174 }
175}
176
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000177bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700178 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800179 ALOGE("Key event has invalid action code 0x%x", action);
180 return false;
181 }
182 return true;
183}
184
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000185bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700187 case AMOTION_EVENT_ACTION_DOWN:
188 case AMOTION_EVENT_ACTION_UP:
189 case AMOTION_EVENT_ACTION_CANCEL:
190 case AMOTION_EVENT_ACTION_MOVE:
191 case AMOTION_EVENT_ACTION_OUTSIDE:
192 case AMOTION_EVENT_ACTION_HOVER_ENTER:
193 case AMOTION_EVENT_ACTION_HOVER_MOVE:
194 case AMOTION_EVENT_ACTION_HOVER_EXIT:
195 case AMOTION_EVENT_ACTION_SCROLL:
196 return true;
197 case AMOTION_EVENT_ACTION_POINTER_DOWN:
198 case AMOTION_EVENT_ACTION_POINTER_UP: {
199 int32_t index = getMotionEventActionPointerIndex(action);
200 return index >= 0 && index < pointerCount;
201 }
202 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
203 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
204 return actionButton != 0;
205 default:
206 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800207 }
208}
209
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000210int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500211 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
212}
213
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000214bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
215 const PointerProperties* pointerProperties) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700216 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217 ALOGE("Motion event has invalid action code 0x%x", action);
218 return false;
219 }
220 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000221 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700222 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800223 return false;
224 }
225 BitSet32 pointerIdBits;
226 for (size_t i = 0; i < pointerCount; i++) {
227 int32_t id = pointerProperties[i].id;
228 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700229 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
230 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800231 return false;
232 }
233 if (pointerIdBits.hasBit(id)) {
234 ALOGE("Motion event has duplicate pointer id %d", id);
235 return false;
236 }
237 pointerIdBits.markBit(id);
238 }
239 return true;
240}
241
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000242std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800243 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000244 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800245 }
246
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000247 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800248 bool first = true;
249 Region::const_iterator cur = region.begin();
250 Region::const_iterator const tail = region.end();
251 while (cur != tail) {
252 if (first) {
253 first = false;
254 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800255 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800256 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800257 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800258 cur++;
259 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000260 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800261}
262
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000263std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500264 constexpr size_t maxEntries = 50; // max events to print
265 constexpr size_t skipBegin = maxEntries / 2;
266 const size_t skipEnd = queue.size() - maxEntries / 2;
267 // skip from maxEntries / 2 ... size() - maxEntries/2
268 // only print from 0 .. skipBegin and then from skipEnd .. size()
269
270 std::string dump;
271 for (size_t i = 0; i < queue.size(); i++) {
272 const DispatchEntry& entry = *queue[i];
273 if (i >= skipBegin && i < skipEnd) {
274 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
275 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
276 continue;
277 }
278 dump.append(INDENT4);
279 dump += entry.eventEntry->getDescription();
280 dump += StringPrintf(", seq=%" PRIu32
281 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
282 entry.seq, entry.targetFlags, entry.resolvedAction,
283 ns2ms(currentTime - entry.eventEntry->eventTime));
284 if (entry.deliveryTime != 0) {
285 // This entry was delivered, so add information on how long we've been waiting
286 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
287 }
288 dump.append("\n");
289 }
290 return dump;
291}
292
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700293/**
294 * Find the entry in std::unordered_map by key, and return it.
295 * If the entry is not found, return a default constructed entry.
296 *
297 * Useful when the entries are vectors, since an empty vector will be returned
298 * if the entry is not found.
299 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
300 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700301template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000302V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700303 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700304 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800305}
306
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000307bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700308 if (first == second) {
309 return true;
310 }
311
312 if (first == nullptr || second == nullptr) {
313 return false;
314 }
315
316 return first->getToken() == second->getToken();
317}
318
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000319bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000320 if (first == nullptr || second == nullptr) {
321 return false;
322 }
323 return first->applicationInfo.token != nullptr &&
324 first->applicationInfo.token == second->applicationInfo.token;
325}
326
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000327bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800328 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
329}
330
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000331std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
332 std::shared_ptr<EventEntry> eventEntry,
333 int32_t inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700334 if (inputTarget.useDefaultPointerTransform()) {
335 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700336 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700337 inputTarget.displayTransform,
338 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000339 }
340
341 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
342 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
343
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700344 std::vector<PointerCoords> pointerCoords;
345 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000346
347 // Use the first pointer information to normalize all other pointers. This could be any pointer
348 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700349 // uses the transform for the normalized pointer.
350 const ui::Transform& firstPointerTransform =
351 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
352 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000353
354 // Iterate through all pointers in the event to normalize against the first.
355 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
356 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
357 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700358 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000359
360 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700361 // First, apply the current pointer's transform to update the coordinates into
362 // window space.
363 pointerCoords[pointerIndex].transform(currTransform);
364 // Next, apply the inverse transform of the normalized coordinates so the
365 // current coordinates are transformed into the normalized coordinate space.
366 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000367 }
368
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700369 std::unique_ptr<MotionEntry> combinedMotionEntry =
370 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
371 motionEntry.deviceId, motionEntry.source,
372 motionEntry.displayId, motionEntry.policyFlags,
373 motionEntry.action, motionEntry.actionButton,
374 motionEntry.flags, motionEntry.metaState,
375 motionEntry.buttonState, motionEntry.classification,
376 motionEntry.edgeFlags, motionEntry.xPrecision,
377 motionEntry.yPrecision, motionEntry.xCursorPosition,
378 motionEntry.yCursorPosition, motionEntry.downTime,
379 motionEntry.pointerCount, motionEntry.pointerProperties,
Prabir Pradhan5beda762021-12-10 09:30:08 +0000380 pointerCoords.data());
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000381
382 if (motionEntry.injectionState) {
383 combinedMotionEntry->injectionState = motionEntry.injectionState;
384 combinedMotionEntry->injectionState->refCount += 1;
385 }
386
387 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700388 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700389 firstPointerTransform, inputTarget.displayTransform,
390 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000391 return dispatchEntry;
392}
393
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000394status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
395 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700396 std::unique_ptr<InputChannel> uniqueServerChannel;
397 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
398
399 serverChannel = std::move(uniqueServerChannel);
400 return result;
401}
402
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500403template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000404bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500405 if (lhs == nullptr && rhs == nullptr) {
406 return true;
407 }
408 if (lhs == nullptr || rhs == nullptr) {
409 return false;
410 }
411 return *lhs == *rhs;
412}
413
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000414sp<IPlatformCompatNative> getCompatService() {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000415 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
416 if (service == nullptr) {
417 ALOGE("Failed to link to compat service");
418 return nullptr;
419 }
420 return interface_cast<IPlatformCompatNative>(service);
421}
422
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000423KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000424 KeyEvent event;
425 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
426 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
427 entry.repeatCount, entry.downTime, entry.eventTime);
428 return event;
429}
430
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000431std::optional<int32_t> findMonitorPidByToken(
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000432 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
433 const sp<IBinder>& token) {
434 for (const auto& it : monitorsByDisplay) {
435 const std::vector<Monitor>& monitors = it.second;
436 for (const Monitor& monitor : monitors) {
437 if (monitor.inputChannel->getConnectionToken() == token) {
438 return monitor.pid;
439 }
440 }
441 }
442 return std::nullopt;
443}
444
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000445bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000446 // Do not keep track of gesture monitors. They receive every event and would disproportionately
447 // affect the statistics.
448 if (connection.monitor) {
449 return false;
450 }
451 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
452 if (!connection.responsive) {
453 return false;
454 }
455 return true;
456}
457
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000458bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000459 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
460 const int32_t& inputEventId = eventEntry.id;
461 if (inputEventId != dispatchEntry.resolvedEventId) {
462 // Event was transmuted
463 return false;
464 }
465 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
466 return false;
467 }
468 // Only track latency for events that originated from hardware
469 if (eventEntry.isSynthesized()) {
470 return false;
471 }
472 const EventEntry::Type& inputEventEntryType = eventEntry.type;
473 if (inputEventEntryType == EventEntry::Type::KEY) {
474 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
475 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
476 return false;
477 }
478 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
479 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
480 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
481 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
482 return false;
483 }
484 } else {
485 // Not a key or a motion
486 return false;
487 }
488 if (!shouldReportMetricsForConnection(connection)) {
489 return false;
490 }
491 return true;
492}
493
Prabir Pradhancef936d2021-07-21 16:17:52 +0000494/**
495 * Connection is responsive if it has no events in the waitQueue that are older than the
496 * current time.
497 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000498bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000499 const nsecs_t currentTime = now();
500 for (const DispatchEntry* entry : connection.waitQueue) {
501 if (entry->timeoutTime < currentTime) {
502 return false;
503 }
504 }
505 return true;
506}
507
Antonio Kantekf16f2832021-09-28 04:39:20 +0000508// Returns true if the event type passed as argument represents a user activity.
509bool isUserActivityEvent(const EventEntry& eventEntry) {
510 switch (eventEntry.type) {
511 case EventEntry::Type::FOCUS:
512 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
513 case EventEntry::Type::DRAG:
514 case EventEntry::Type::TOUCH_MODE_CHANGED:
515 case EventEntry::Type::SENSOR:
516 case EventEntry::Type::CONFIGURATION_CHANGED:
517 return false;
518 case EventEntry::Type::DEVICE_RESET:
519 case EventEntry::Type::KEY:
520 case EventEntry::Type::MOTION:
521 return true;
522 }
523}
524
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800525// Returns true if the given window can accept pointer events at the given display location.
Prabir Pradhand65552b2021-10-07 11:23:50 -0700526bool windowAcceptsTouchAt(const WindowInfo& windowInfo, int32_t displayId, int32_t x, int32_t y,
527 bool isStylus) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800528 if (windowInfo.displayId != displayId || !windowInfo.visible) {
529 return false;
530 }
531 const auto flags = windowInfo.flags;
Prabir Pradhand65552b2021-10-07 11:23:50 -0700532 const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
533 if (flags.test(WindowInfo::Flag::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800534 return false;
535 }
536 const bool isModalWindow = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
537 !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
538 if (!isModalWindow && !windowInfo.touchableRegionContainsPoint(x, y)) {
539 return false;
540 }
541 return true;
542}
543
Prabir Pradhand65552b2021-10-07 11:23:50 -0700544bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
545 return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
546 (entry.pointerProperties[pointerIndex].toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS ||
547 entry.pointerProperties[pointerIndex].toolType == AMOTION_EVENT_TOOL_TYPE_ERASER);
548}
549
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000550} // namespace
551
Michael Wrightd02c5b62014-02-10 15:10:22 -0800552// --- InputDispatcher ---
553
Garfield Tan00f511d2019-06-12 16:55:40 -0700554InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
555 : mPolicy(policy),
556 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700557 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800558 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700559 mAppSwitchSawKeyDown(false),
560 mAppSwitchDueTime(LONG_LONG_MAX),
561 mNextUnblockedEvent(nullptr),
562 mDispatchEnabled(false),
563 mDispatchFrozen(false),
564 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800565 // mInTouchMode will be initialized by the WindowManager to the default device config.
566 // To avoid leaking stack in case that call never comes, and for tests,
567 // initialize it here anyways.
Antonio Kantekf16f2832021-09-28 04:39:20 +0000568 mInTouchMode(kDefaultInTouchMode),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100569 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000570 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800571 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000572 mLatencyAggregator(),
573 mLatencyTracker(&mLatencyAggregator),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000574 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800575 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800576 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800577
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700578 mWindowInfoListener = new DispatcherWindowListener(*this);
579 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
580
Yi Kong9b14ac62018-07-17 13:48:38 -0700581 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800582
583 policy->getDispatcherConfiguration(&mConfig);
584}
585
586InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000587 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800588
Prabir Pradhancef936d2021-07-21 16:17:52 +0000589 resetKeyRepeatLocked();
590 releasePendingEventLocked();
591 drainInboundQueueLocked();
592 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800593
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000594 while (!mConnectionsByToken.empty()) {
595 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000596 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
597 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800598 }
599}
600
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700601status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700602 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700603 return ALREADY_EXISTS;
604 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700605 mThread = std::make_unique<InputThread>(
606 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
607 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700608}
609
610status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700611 if (mThread && mThread->isCallingThread()) {
612 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700613 return INVALID_OPERATION;
614 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700615 mThread.reset();
616 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700617}
618
Michael Wrightd02c5b62014-02-10 15:10:22 -0800619void InputDispatcher::dispatchOnce() {
620 nsecs_t nextWakeupTime = LONG_LONG_MAX;
621 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800622 std::scoped_lock _l(mLock);
623 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800624
625 // Run a dispatch loop if there are no pending commands.
626 // The dispatch loop might enqueue commands to run afterwards.
627 if (!haveCommandsLocked()) {
628 dispatchOnceInnerLocked(&nextWakeupTime);
629 }
630
631 // Run all pending commands if there are any.
632 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000633 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800634 nextWakeupTime = LONG_LONG_MIN;
635 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800636
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700637 // If we are still waiting for ack on some events,
638 // we might have to wake up earlier to check if an app is anr'ing.
639 const nsecs_t nextAnrCheck = processAnrsLocked();
640 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
641
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800642 // We are about to enter an infinitely long sleep, because we have no commands or
643 // pending or queued events
644 if (nextWakeupTime == LONG_LONG_MAX) {
645 mDispatcherEnteredIdle.notify_all();
646 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800647 } // release lock
648
649 // Wait for callback or timeout or wake. (make sure we round up, not down)
650 nsecs_t currentTime = now();
651 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
652 mLooper->pollOnce(timeoutMillis);
653}
654
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700655/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500656 * Raise ANR if there is no focused window.
657 * Before the ANR is raised, do a final state check:
658 * 1. The currently focused application must be the same one we are waiting for.
659 * 2. Ensure we still don't have a focused window.
660 */
661void InputDispatcher::processNoFocusedWindowAnrLocked() {
662 // Check if the application that we are waiting for is still focused.
663 std::shared_ptr<InputApplicationHandle> focusedApplication =
664 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
665 if (focusedApplication == nullptr ||
666 focusedApplication->getApplicationToken() !=
667 mAwaitedFocusedApplication->getApplicationToken()) {
668 // Unexpected because we should have reset the ANR timer when focused application changed
669 ALOGE("Waited for a focused window, but focused application has already changed to %s",
670 focusedApplication->getName().c_str());
671 return; // The focused application has changed.
672 }
673
chaviw98318de2021-05-19 16:45:23 -0500674 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500675 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
676 if (focusedWindowHandle != nullptr) {
677 return; // We now have a focused window. No need for ANR.
678 }
679 onAnrLocked(mAwaitedFocusedApplication);
680}
681
682/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700683 * Check if any of the connections' wait queues have events that are too old.
684 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
685 * Return the time at which we should wake up next.
686 */
687nsecs_t InputDispatcher::processAnrsLocked() {
688 const nsecs_t currentTime = now();
689 nsecs_t nextAnrCheck = LONG_LONG_MAX;
690 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
691 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
692 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500693 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700694 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500695 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700696 return LONG_LONG_MIN;
697 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500698 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700699 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
700 }
701 }
702
703 // Check if any connection ANRs are due
704 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
705 if (currentTime < nextAnrCheck) { // most likely scenario
706 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
707 }
708
709 // If we reached here, we have an unresponsive connection.
710 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
711 if (connection == nullptr) {
712 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
713 return nextAnrCheck;
714 }
715 connection->responsive = false;
716 // Stop waking up for this unresponsive connection
717 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000718 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700719 return LONG_LONG_MIN;
720}
721
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500722std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
chaviw98318de2021-05-19 16:45:23 -0500723 sp<WindowInfoHandle> window = getWindowHandleLocked(token);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700724 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500725 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700726 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500727 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700728}
729
Michael Wrightd02c5b62014-02-10 15:10:22 -0800730void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
731 nsecs_t currentTime = now();
732
Jeff Browndc5992e2014-04-11 01:27:26 -0700733 // Reset the key repeat timer whenever normal dispatch is suspended while the
734 // device is in a non-interactive state. This is to ensure that we abort a key
735 // repeat if the device is just coming out of sleep.
736 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800737 resetKeyRepeatLocked();
738 }
739
740 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
741 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100742 if (DEBUG_FOCUS) {
743 ALOGD("Dispatch frozen. Waiting some more.");
744 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800745 return;
746 }
747
748 // Optimize latency of app switches.
749 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
750 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
751 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
752 if (mAppSwitchDueTime < *nextWakeupTime) {
753 *nextWakeupTime = mAppSwitchDueTime;
754 }
755
756 // Ready to start a new event.
757 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700758 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700759 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800760 if (isAppSwitchDue) {
761 // The inbound queue is empty so the app switch key we were waiting
762 // for will never arrive. Stop waiting for it.
763 resetPendingAppSwitchLocked(false);
764 isAppSwitchDue = false;
765 }
766
767 // Synthesize a key repeat if appropriate.
768 if (mKeyRepeatState.lastKeyEntry) {
769 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
770 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
771 } else {
772 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
773 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
774 }
775 }
776 }
777
778 // Nothing to do if there is no pending event.
779 if (!mPendingEvent) {
780 return;
781 }
782 } else {
783 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700784 mPendingEvent = mInboundQueue.front();
785 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800786 traceInboundQueueLengthLocked();
787 }
788
789 // Poke user activity for this event.
790 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700791 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800792 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800793 }
794
795 // Now we have an event to dispatch.
796 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700797 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800798 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700799 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800800 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700801 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800802 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700803 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800804 }
805
806 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700807 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800808 }
809
810 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700811 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700812 const ConfigurationChangedEntry& typedEntry =
813 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700814 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700815 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700816 break;
817 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800818
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700819 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700820 const DeviceResetEntry& typedEntry =
821 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700822 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700823 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700824 break;
825 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800826
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100827 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700828 std::shared_ptr<FocusEntry> typedEntry =
829 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100830 dispatchFocusLocked(currentTime, typedEntry);
831 done = true;
832 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
833 break;
834 }
835
Antonio Kantek7242d8b2021-08-05 16:07:20 -0700836 case EventEntry::Type::TOUCH_MODE_CHANGED: {
837 const auto typedEntry = std::static_pointer_cast<TouchModeEntry>(mPendingEvent);
838 dispatchTouchModeChangeLocked(currentTime, typedEntry);
839 done = true;
840 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
841 break;
842 }
843
Prabir Pradhan99987712020-11-10 18:43:05 -0800844 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
845 const auto typedEntry =
846 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
847 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
848 done = true;
849 break;
850 }
851
arthurhungb89ccb02020-12-30 16:19:01 +0800852 case EventEntry::Type::DRAG: {
853 std::shared_ptr<DragEntry> typedEntry =
854 std::static_pointer_cast<DragEntry>(mPendingEvent);
855 dispatchDragLocked(currentTime, typedEntry);
856 done = true;
857 break;
858 }
859
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700860 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700861 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700862 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700863 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700864 resetPendingAppSwitchLocked(true);
865 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700866 } else if (dropReason == DropReason::NOT_DROPPED) {
867 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700868 }
869 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700870 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700871 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700872 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700873 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
874 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700875 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700876 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700877 break;
878 }
879
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700880 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700881 std::shared_ptr<MotionEntry> motionEntry =
882 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700883 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
884 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800885 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700886 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700887 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700888 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700889 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
890 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700891 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700892 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700893 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800894 }
Chris Yef59a2f42020-10-16 12:55:26 -0700895
896 case EventEntry::Type::SENSOR: {
897 std::shared_ptr<SensorEntry> sensorEntry =
898 std::static_pointer_cast<SensorEntry>(mPendingEvent);
899 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
900 dropReason = DropReason::APP_SWITCH;
901 }
902 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
903 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
904 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
905 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
906 dropReason = DropReason::STALE;
907 }
908 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
909 done = true;
910 break;
911 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800912 }
913
914 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700915 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700916 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800917 }
Michael Wright3a981722015-06-10 15:26:13 +0100918 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800919
920 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700921 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800922 }
923}
924
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700925/**
926 * Return true if the events preceding this incoming motion event should be dropped
927 * Return false otherwise (the default behaviour)
928 */
929bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700930 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -0700931 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700932
933 // Optimize case where the current application is unresponsive and the user
934 // decides to touch a window in a different application.
935 // If the application takes too long to catch up then we drop all events preceding
936 // the touch into the other window.
937 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700938 int32_t displayId = motionEntry.displayId;
939 int32_t x = static_cast<int32_t>(
940 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
941 int32_t y = static_cast<int32_t>(
942 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Prabir Pradhand65552b2021-10-07 11:23:50 -0700943
944 const bool isStylus = isPointerFromStylus(motionEntry, 0 /*pointerIndex*/);
chaviw98318de2021-05-19 16:45:23 -0500945 sp<WindowInfoHandle> touchedWindowHandle =
Prabir Pradhand65552b2021-10-07 11:23:50 -0700946 findTouchedWindowAtLocked(displayId, x, y, nullptr, isStylus);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700947 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700948 touchedWindowHandle->getApplicationToken() !=
949 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700950 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700951 ALOGI("Pruning input queue because user touched a different application while waiting "
952 "for %s",
953 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700954 return true;
955 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700956
957 // Alternatively, maybe there's a gesture monitor that could handle this event
Prabir Pradhan0a99c922021-09-03 08:27:53 -0700958 for (const auto& monitor : getValueByKey(mGestureMonitorsByDisplay, displayId)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700959 sp<Connection> connection =
Prabir Pradhan0a99c922021-09-03 08:27:53 -0700960 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000961 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700962 // This monitor could take more input. Drop all events preceding this
963 // event, so that gesture monitor could get a chance to receive the stream
964 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
965 "responsive gesture monitor that may handle the event",
966 mAwaitedFocusedApplication->getName().c_str());
967 return true;
968 }
969 }
970 }
971
972 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
973 // yet been processed by some connections, the dispatcher will wait for these motion
974 // events to be processed before dispatching the key event. This is because these motion events
975 // may cause a new window to be launched, which the user might expect to receive focus.
976 // To prevent waiting forever for such events, just send the key to the currently focused window
977 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
978 ALOGD("Received a new pointer down event, stop waiting for events to process and "
979 "just send the pending key event to the focused window.");
980 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700981 }
982 return false;
983}
984
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700985bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700986 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700987 mInboundQueue.push_back(std::move(newEntry));
988 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800989 traceInboundQueueLengthLocked();
990
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700991 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700992 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700993 // Optimize app switch latency.
994 // If the application takes too long to catch up then we drop all events preceding
995 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700996 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700997 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700998 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700999 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001000 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001001 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001002 if (DEBUG_APP_SWITCH) {
1003 ALOGD("App switch is pending!");
1004 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001005 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001006 mAppSwitchSawKeyDown = false;
1007 needWake = true;
1008 }
1009 }
1010 }
1011 break;
1012 }
1013
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001014 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001015 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
1016 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001017 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001018 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001019 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001020 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001021 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001022 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1023 break;
1024 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001025 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001026 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001027 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001028 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001029 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1030 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001031 // nothing to do
1032 break;
1033 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001034 }
1035
1036 return needWake;
1037}
1038
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001039void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001040 // Do not store sensor event in recent queue to avoid flooding the queue.
1041 if (entry->type != EventEntry::Type::SENSOR) {
1042 mRecentQueue.push_back(entry);
1043 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001044 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001045 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001046 }
1047}
1048
chaviw98318de2021-05-19 16:45:23 -05001049sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1050 int32_t y, TouchState* touchState,
Prabir Pradhand65552b2021-10-07 11:23:50 -07001051 bool isStylus,
chaviw98318de2021-05-19 16:45:23 -05001052 bool addOutsideTargets,
1053 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001054 if (addOutsideTargets && touchState == nullptr) {
1055 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001056 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001057 // Traverse windows from front to back to find touched window.
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001058 const auto& windowHandles = getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05001059 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001060 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001061 continue;
1062 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001063
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001064 const WindowInfo& info = *windowHandle->getInfo();
Prabir Pradhand65552b2021-10-07 11:23:50 -07001065 if (!info.isSpy() && windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001066 return windowHandle;
1067 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001068
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001069 if (addOutsideTargets && info.flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
1070 touchState->addOrUpdateWindow(windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1071 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001072 }
1073 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001074 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001075}
1076
Prabir Pradhand65552b2021-10-07 11:23:50 -07001077std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
1078 int32_t displayId, int32_t x, int32_t y, bool isStylus) const {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001079 // Traverse windows from front to back and gather the touched spy windows.
1080 std::vector<sp<WindowInfoHandle>> spyWindows;
1081 const auto& windowHandles = getWindowHandlesLocked(displayId);
1082 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1083 const WindowInfo& info = *windowHandle->getInfo();
1084
Prabir Pradhand65552b2021-10-07 11:23:50 -07001085 if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001086 continue;
1087 }
1088 if (!info.isSpy()) {
1089 // The first touched non-spy window was found, so return the spy windows touched so far.
1090 return spyWindows;
1091 }
1092 spyWindows.push_back(windowHandle);
1093 }
1094 return spyWindows;
1095}
1096
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001097void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001098 const char* reason;
1099 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001100 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001101 if (DEBUG_INBOUND_EVENT_DETAILS) {
1102 ALOGD("Dropped event because policy consumed it.");
1103 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001104 reason = "inbound event was dropped because the policy consumed it";
1105 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001106 case DropReason::DISABLED:
1107 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001108 ALOGI("Dropped event because input dispatch is disabled.");
1109 }
1110 reason = "inbound event was dropped because input dispatch is disabled";
1111 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001112 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001113 ALOGI("Dropped event because of pending overdue app switch.");
1114 reason = "inbound event was dropped because of pending overdue app switch";
1115 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001116 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001117 ALOGI("Dropped event because the current application is not responding and the user "
1118 "has started interacting with a different application.");
1119 reason = "inbound event was dropped because the current application is not responding "
1120 "and the user has started interacting with a different application";
1121 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001122 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001123 ALOGI("Dropped event because it is stale.");
1124 reason = "inbound event was dropped because it is stale";
1125 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001126 case DropReason::NO_POINTER_CAPTURE:
1127 ALOGI("Dropped event because there is no window with Pointer Capture.");
1128 reason = "inbound event was dropped because there is no window with Pointer Capture";
1129 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001130 case DropReason::NOT_DROPPED: {
1131 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001132 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001133 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001134 }
1135
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001136 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001137 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001138 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1139 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001140 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001141 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001142 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001143 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1144 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001145 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1146 synthesizeCancelationEventsForAllConnectionsLocked(options);
1147 } else {
1148 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1149 synthesizeCancelationEventsForAllConnectionsLocked(options);
1150 }
1151 break;
1152 }
Chris Yef59a2f42020-10-16 12:55:26 -07001153 case EventEntry::Type::SENSOR: {
1154 break;
1155 }
arthurhungb89ccb02020-12-30 16:19:01 +08001156 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1157 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001158 break;
1159 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001160 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001161 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001162 case EventEntry::Type::CONFIGURATION_CHANGED:
1163 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001164 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001165 break;
1166 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001167 }
1168}
1169
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001170static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001171 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1172 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001173}
1174
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001175bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1176 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1177 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1178 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001179}
1180
1181bool InputDispatcher::isAppSwitchPendingLocked() {
1182 return mAppSwitchDueTime != LONG_LONG_MAX;
1183}
1184
1185void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1186 mAppSwitchDueTime = LONG_LONG_MAX;
1187
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001188 if (DEBUG_APP_SWITCH) {
1189 if (handled) {
1190 ALOGD("App switch has arrived.");
1191 } else {
1192 ALOGD("App switch was abandoned.");
1193 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001194 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001195}
1196
Michael Wrightd02c5b62014-02-10 15:10:22 -08001197bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001198 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001199}
1200
Prabir Pradhancef936d2021-07-21 16:17:52 +00001201bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001202 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001203 return false;
1204 }
1205
1206 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001207 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001208 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001209 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1210 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001211 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001212 return true;
1213}
1214
Prabir Pradhancef936d2021-07-21 16:17:52 +00001215void InputDispatcher::postCommandLocked(Command&& command) {
1216 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001217}
1218
1219void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001220 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001221 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001222 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001223 releaseInboundEventLocked(entry);
1224 }
1225 traceInboundQueueLengthLocked();
1226}
1227
1228void InputDispatcher::releasePendingEventLocked() {
1229 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001230 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001231 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001232 }
1233}
1234
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001235void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001236 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001237 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001238 if (DEBUG_DISPATCH_CYCLE) {
1239 ALOGD("Injected inbound event was dropped.");
1240 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001241 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001242 }
1243 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001244 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001245 }
1246 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001247}
1248
1249void InputDispatcher::resetKeyRepeatLocked() {
1250 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001251 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001252 }
1253}
1254
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001255std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1256 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001257
Michael Wright2e732952014-09-24 13:26:59 -07001258 uint32_t policyFlags = entry->policyFlags &
1259 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001260
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001261 std::shared_ptr<KeyEntry> newEntry =
1262 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1263 entry->source, entry->displayId, policyFlags, entry->action,
1264 entry->flags, entry->keyCode, entry->scanCode,
1265 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001266
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001267 newEntry->syntheticRepeat = true;
1268 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001269 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001270 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001271}
1272
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001273bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001274 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001275 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1276 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1277 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001278
1279 // Reset key repeating in case a keyboard device was added or removed or something.
1280 resetKeyRepeatLocked();
1281
1282 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001283 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1284 scoped_unlock unlock(mLock);
1285 mPolicy->notifyConfigurationChanged(eventTime);
1286 };
1287 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001288 return true;
1289}
1290
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001291bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1292 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001293 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1294 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1295 entry.deviceId);
1296 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001297
liushenxiang42232912021-05-21 20:24:09 +08001298 // Reset key repeating in case a keyboard device was disabled or enabled.
1299 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1300 resetKeyRepeatLocked();
1301 }
1302
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001303 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001304 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001305 synthesizeCancelationEventsForAllConnectionsLocked(options);
1306 return true;
1307}
1308
Vishnu Nairad321cd2020-08-20 16:40:21 -07001309void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001310 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001311 if (mPendingEvent != nullptr) {
1312 // Move the pending event to the front of the queue. This will give the chance
1313 // for the pending event to get dispatched to the newly focused window
1314 mInboundQueue.push_front(mPendingEvent);
1315 mPendingEvent = nullptr;
1316 }
1317
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001318 std::unique_ptr<FocusEntry> focusEntry =
1319 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1320 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001321
1322 // This event should go to the front of the queue, but behind all other focus events
1323 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001324 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001325 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001326 [](const std::shared_ptr<EventEntry>& event) {
1327 return event->type == EventEntry::Type::FOCUS;
1328 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001329
1330 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001331 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001332}
1333
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001334void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001335 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001336 if (channel == nullptr) {
1337 return; // Window has gone away
1338 }
1339 InputTarget target;
1340 target.inputChannel = channel;
1341 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1342 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001343 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1344 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001345 std::string reason = std::string("reason=").append(entry->reason);
1346 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001347 dispatchEventLocked(currentTime, entry, {target});
1348}
1349
Prabir Pradhan99987712020-11-10 18:43:05 -08001350void InputDispatcher::dispatchPointerCaptureChangedLocked(
1351 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1352 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001353 dropReason = DropReason::NOT_DROPPED;
1354
Prabir Pradhan99987712020-11-10 18:43:05 -08001355 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001356 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001357
1358 if (entry->pointerCaptureRequest.enable) {
1359 // Enable Pointer Capture.
1360 if (haveWindowWithPointerCapture &&
1361 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1362 LOG_ALWAYS_FATAL("This request to enable Pointer Capture has already been dispatched "
1363 "to the window.");
1364 }
1365 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001366 // This can happen if a window requests capture and immediately releases capture.
1367 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001368 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001369 return;
1370 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001371 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1372 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1373 return;
1374 }
1375
Vishnu Nairc519ff72021-01-21 08:23:08 -08001376 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001377 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1378 mWindowTokenWithPointerCapture = token;
1379 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001380 // Disable Pointer Capture.
1381 // We do not check if the sequence number matches for requests to disable Pointer Capture
1382 // for two reasons:
1383 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1384 // to disable capture with the same sequence number: one generated by
1385 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1386 // Capture being disabled in InputReader.
1387 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1388 // actual Pointer Capture state that affects events being generated by input devices is
1389 // in InputReader.
1390 if (!haveWindowWithPointerCapture) {
1391 // Pointer capture was already forcefully disabled because of focus change.
1392 dropReason = DropReason::NOT_DROPPED;
1393 return;
1394 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001395 token = mWindowTokenWithPointerCapture;
1396 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001397 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001398 setPointerCaptureLocked(false);
1399 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001400 }
1401
1402 auto channel = getInputChannelLocked(token);
1403 if (channel == nullptr) {
1404 // Window has gone away, clean up Pointer Capture state.
1405 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001406 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001407 setPointerCaptureLocked(false);
1408 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001409 return;
1410 }
1411 InputTarget target;
1412 target.inputChannel = channel;
1413 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1414 entry->dispatchInProgress = true;
1415 dispatchEventLocked(currentTime, entry, {target});
1416
1417 dropReason = DropReason::NOT_DROPPED;
1418}
1419
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001420void InputDispatcher::dispatchTouchModeChangeLocked(nsecs_t currentTime,
1421 const std::shared_ptr<TouchModeEntry>& entry) {
1422 const std::vector<sp<WindowInfoHandle>>& windowHandles =
1423 getWindowHandlesLocked(mFocusedDisplayId);
1424 if (windowHandles.empty()) {
1425 return;
1426 }
1427 const std::vector<InputTarget> inputTargets =
1428 getInputTargetsFromWindowHandlesLocked(windowHandles);
1429 if (inputTargets.empty()) {
1430 return;
1431 }
1432 entry->dispatchInProgress = true;
1433 dispatchEventLocked(currentTime, entry, inputTargets);
1434}
1435
1436std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1437 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1438 std::vector<InputTarget> inputTargets;
1439 for (const sp<WindowInfoHandle>& handle : windowHandles) {
1440 // TODO(b/193718270): Due to performance concerns, consider notifying visible windows only.
1441 const sp<IBinder>& token = handle->getToken();
1442 if (token == nullptr) {
1443 continue;
1444 }
1445 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1446 if (channel == nullptr) {
1447 continue; // Window has gone away
1448 }
1449 InputTarget target;
1450 target.inputChannel = channel;
1451 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1452 inputTargets.push_back(target);
1453 }
1454 return inputTargets;
1455}
1456
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001457bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001458 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001459 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001460 if (!entry->dispatchInProgress) {
1461 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1462 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1463 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1464 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001465 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001466 // We have seen two identical key downs in a row which indicates that the device
1467 // driver is automatically generating key repeats itself. We take note of the
1468 // repeat here, but we disable our own next key repeat timer since it is clear that
1469 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001470 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1471 // Make sure we don't get key down from a different device. If a different
1472 // device Id has same key pressed down, the new device Id will replace the
1473 // current one to hold the key repeat with repeat count reset.
1474 // In the future when got a KEY_UP on the device id, drop it and do not
1475 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001476 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1477 resetKeyRepeatLocked();
1478 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1479 } else {
1480 // Not a repeat. Save key down state in case we do see a repeat later.
1481 resetKeyRepeatLocked();
1482 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1483 }
1484 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001485 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1486 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001487 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001488 if (DEBUG_INBOUND_EVENT_DETAILS) {
1489 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1490 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001491 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001492 resetKeyRepeatLocked();
1493 }
1494
1495 if (entry->repeatCount == 1) {
1496 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1497 } else {
1498 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1499 }
1500
1501 entry->dispatchInProgress = true;
1502
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001503 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001504 }
1505
1506 // Handle case where the policy asked us to try again later last time.
1507 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1508 if (currentTime < entry->interceptKeyWakeupTime) {
1509 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1510 *nextWakeupTime = entry->interceptKeyWakeupTime;
1511 }
1512 return false; // wait until next wakeup
1513 }
1514 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1515 entry->interceptKeyWakeupTime = 0;
1516 }
1517
1518 // Give the policy a chance to intercept the key.
1519 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1520 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001521 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001522 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001523
1524 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1525 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1526 };
1527 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001528 return false; // wait for the command to run
1529 } else {
1530 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1531 }
1532 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001533 if (*dropReason == DropReason::NOT_DROPPED) {
1534 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001535 }
1536 }
1537
1538 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001539 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001540 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001541 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1542 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001543 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001544 return true;
1545 }
1546
1547 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001548 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001549 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001550 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001551 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001552 return false;
1553 }
1554
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001555 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001556 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001557 return true;
1558 }
1559
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001560 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001561 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001562
1563 // Dispatch the key.
1564 dispatchEventLocked(currentTime, entry, inputTargets);
1565 return true;
1566}
1567
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001568void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001569 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1570 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1571 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1572 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1573 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1574 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1575 entry.metaState, entry.repeatCount, entry.downTime);
1576 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001577}
1578
Prabir Pradhancef936d2021-07-21 16:17:52 +00001579void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1580 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001581 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001582 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1583 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1584 "source=0x%x, sensorType=%s",
1585 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001586 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001587 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001588 auto command = [this, entry]() REQUIRES(mLock) {
1589 scoped_unlock unlock(mLock);
1590
1591 if (entry->accuracyChanged) {
1592 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1593 }
1594 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1595 entry->hwTimestamp, entry->values);
1596 };
1597 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001598}
1599
1600bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001601 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1602 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001603 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001604 }
Chris Yef59a2f42020-10-16 12:55:26 -07001605 { // acquire lock
1606 std::scoped_lock _l(mLock);
1607
1608 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1609 std::shared_ptr<EventEntry> entry = *it;
1610 if (entry->type == EventEntry::Type::SENSOR) {
1611 it = mInboundQueue.erase(it);
1612 releaseInboundEventLocked(entry);
1613 }
1614 }
1615 }
1616 return true;
1617}
1618
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001619bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001620 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001621 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001622 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001623 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001624 entry->dispatchInProgress = true;
1625
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001626 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001627 }
1628
1629 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001630 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001631 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001632 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1633 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001634 return true;
1635 }
1636
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001637 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001638
1639 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001640 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001641
1642 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001643 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001644 if (isPointerEvent) {
1645 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001646 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001647 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001648 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001649 } else {
1650 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001651 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001652 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001653 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001654 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001655 return false;
1656 }
1657
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001658 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001659 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001660 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1661 return true;
1662 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001663 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001664 CancelationOptions::Mode mode(isPointerEvent
1665 ? CancelationOptions::CANCEL_POINTER_EVENTS
1666 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1667 CancelationOptions options(mode, "input event injection failed");
1668 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001669 return true;
1670 }
1671
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001672 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001673 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001674
1675 // Dispatch the motion.
1676 if (conflictingPointerActions) {
1677 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001678 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001679 synthesizeCancelationEventsForAllConnectionsLocked(options);
1680 }
1681 dispatchEventLocked(currentTime, entry, inputTargets);
1682 return true;
1683}
1684
chaviw98318de2021-05-19 16:45:23 -05001685void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001686 bool isExiting, const MotionEntry& motionEntry) {
1687 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1688 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1689 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1690 PointerCoords pointerCoords;
1691 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1692 pointerCoords.transform(windowHandle->getInfo()->transform);
1693
1694 std::unique_ptr<DragEntry> dragEntry =
1695 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1696 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1697 pointerCoords.getY());
1698
1699 enqueueInboundEventLocked(std::move(dragEntry));
1700}
1701
1702void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1703 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1704 if (channel == nullptr) {
1705 return; // Window has gone away
1706 }
1707 InputTarget target;
1708 target.inputChannel = channel;
1709 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1710 entry->dispatchInProgress = true;
1711 dispatchEventLocked(currentTime, entry, {target});
1712}
1713
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001714void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001715 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1716 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1717 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001718 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001719 "metaState=0x%x, buttonState=0x%x,"
1720 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1721 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001722 entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
1723 entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.edgeFlags,
1724 entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001725
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001726 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1727 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1728 "x=%f, y=%f, pressure=%f, size=%f, "
1729 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1730 "orientation=%f",
1731 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1732 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1733 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1734 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1735 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1736 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1737 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1738 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1739 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1740 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1741 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001742 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001743}
1744
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001745void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1746 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001747 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001748 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001749 if (DEBUG_DISPATCH_CYCLE) {
1750 ALOGD("dispatchEventToCurrentInputTargets");
1751 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001752
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001753 updateInteractionTokensLocked(*eventEntry, inputTargets);
1754
Michael Wrightd02c5b62014-02-10 15:10:22 -08001755 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1756
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001757 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001758
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001759 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001760 sp<Connection> connection =
1761 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001762 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001763 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001764 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001765 if (DEBUG_FOCUS) {
1766 ALOGD("Dropping event delivery to target with channel '%s' because it "
1767 "is no longer registered with the input dispatcher.",
1768 inputTarget.inputChannel->getName().c_str());
1769 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001770 }
1771 }
1772}
1773
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001774void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1775 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1776 // If the policy decides to close the app, we will get a channel removal event via
1777 // unregisterInputChannel, and will clean up the connection that way. We are already not
1778 // sending new pointers to the connection when it blocked, but focused events will continue to
1779 // pile up.
1780 ALOGW("Canceling events for %s because it is unresponsive",
1781 connection->inputChannel->getName().c_str());
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08001782 if (connection->status == Connection::Status::NORMAL) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001783 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1784 "application not responding");
1785 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001786 }
1787}
1788
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001789void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001790 if (DEBUG_FOCUS) {
1791 ALOGD("Resetting ANR timeouts.");
1792 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001793
1794 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001795 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001796 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001797}
1798
Tiger Huang721e26f2018-07-24 22:26:19 +08001799/**
1800 * Get the display id that the given event should go to. If this event specifies a valid display id,
1801 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1802 * Focused display is the display that the user most recently interacted with.
1803 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001804int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001805 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001806 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001807 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001808 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1809 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001810 break;
1811 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001812 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001813 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1814 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001815 break;
1816 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00001817 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001818 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001819 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001820 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001821 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001822 case EventEntry::Type::SENSOR:
1823 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001824 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001825 return ADISPLAY_ID_NONE;
1826 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001827 }
1828 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1829}
1830
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001831bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1832 const char* focusedWindowName) {
1833 if (mAnrTracker.empty()) {
1834 // already processed all events that we waited for
1835 mKeyIsWaitingForEventsTimeout = std::nullopt;
1836 return false;
1837 }
1838
1839 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1840 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001841 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001842 mKeyIsWaitingForEventsTimeout = currentTime +
1843 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1844 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001845 return true;
1846 }
1847
1848 // We still have pending events, and already started the timer
1849 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1850 return true; // Still waiting
1851 }
1852
1853 // Waited too long, and some connection still hasn't processed all motions
1854 // Just send the key to the focused window
1855 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1856 focusedWindowName);
1857 mKeyIsWaitingForEventsTimeout = std::nullopt;
1858 return false;
1859}
1860
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001861InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1862 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1863 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001864 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001865
Tiger Huang721e26f2018-07-24 22:26:19 +08001866 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001867 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001868 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001869 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1870
Michael Wrightd02c5b62014-02-10 15:10:22 -08001871 // If there is no currently focused window and no focused application
1872 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001873 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1874 ALOGI("Dropping %s event because there is no focused window or focused application in "
1875 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08001876 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001877 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001878 }
1879
Vishnu Nair062a8672021-09-03 16:07:44 -07001880 // Drop key events if requested by input feature
1881 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
1882 return InputEventInjectionResult::FAILED;
1883 }
1884
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001885 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1886 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1887 // start interacting with another application via touch (app switch). This code can be removed
1888 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1889 // an app is expected to have a focused window.
1890 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1891 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1892 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001893 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1894 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1895 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001896 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001897 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001898 ALOGW("Waiting because no window has focus but %s may eventually add a "
1899 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001900 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001901 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001902 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001903 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1904 // Already raised ANR. Drop the event
1905 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08001906 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001907 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001908 } else {
1909 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001910 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001911 }
1912 }
1913
1914 // we have a valid, non-null focused window
1915 resetNoFocusedWindowTimeoutLocked();
1916
Michael Wrightd02c5b62014-02-10 15:10:22 -08001917 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001918 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001919 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920 }
1921
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001922 if (focusedWindowHandle->getInfo()->paused) {
1923 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001924 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001925 }
1926
1927 // If the event is a key event, then we must wait for all previous events to
1928 // complete before delivering it because previous events may have the
1929 // side-effect of transferring focus to a different window and we want to
1930 // ensure that the following keys are sent to the new window.
1931 //
1932 // Suppose the user touches a button in a window then immediately presses "A".
1933 // If the button causes a pop-up window to appear then we want to ensure that
1934 // the "A" key is delivered to the new pop-up window. This is because users
1935 // often anticipate pending UI changes when typing on a keyboard.
1936 // To obtain this behavior, we must serialize key events with respect to all
1937 // prior input events.
1938 if (entry.type == EventEntry::Type::KEY) {
1939 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1940 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001941 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001942 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001943 }
1944
1945 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001946 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001947 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1948 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001949
1950 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001951 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001952}
1953
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001954/**
1955 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1956 * that are currently unresponsive.
1957 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001958std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
1959 const std::vector<Monitor>& monitors) const {
1960 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001961 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001962 [this](const Monitor& monitor) REQUIRES(mLock) {
1963 sp<Connection> connection =
1964 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001965 if (connection == nullptr) {
1966 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001967 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001968 return false;
1969 }
1970 if (!connection->responsive) {
1971 ALOGW("Unresponsive monitor %s will not get the new gesture",
1972 connection->inputChannel->getName().c_str());
1973 return false;
1974 }
1975 return true;
1976 });
1977 return responsiveMonitors;
1978}
1979
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001980InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1981 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1982 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001983 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001984 enum InjectionPermission {
1985 INJECTION_PERMISSION_UNKNOWN,
1986 INJECTION_PERMISSION_GRANTED,
1987 INJECTION_PERMISSION_DENIED
1988 };
1989
Michael Wrightd02c5b62014-02-10 15:10:22 -08001990 // For security reasons, we defer updating the touch state until we are sure that
1991 // event injection will be allowed.
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001992 const int32_t displayId = entry.displayId;
1993 const int32_t action = entry.action;
1994 const int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001995
1996 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001997 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001998 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05001999 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
2000 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002001
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002002 // Copy current touch state into tempTouchState.
2003 // This state will be used to update mTouchStatesByDisplay at the end of this function.
2004 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07002005 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002006 TouchState tempTouchState;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002007 if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
2008 oldState = &(it->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002009 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08002010 }
2011
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002012 bool isSplit = tempTouchState.split;
2013 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
2014 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
2015 tempTouchState.displayId != displayId);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002016
2017 const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2018 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2019 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
2020 const bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2021 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002022 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002023 bool wrongDevice = false;
2024 if (newGesture) {
2025 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002026 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002027 ALOGI("Dropping event because a pointer for a different device is already down "
2028 "in display %" PRId32,
2029 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002030 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002031 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002032 switchedDevice = false;
2033 wrongDevice = true;
2034 goto Failed;
2035 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002036 tempTouchState.reset();
2037 tempTouchState.down = down;
2038 tempTouchState.deviceId = entry.deviceId;
2039 tempTouchState.source = entry.source;
2040 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002041 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002042 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002043 ALOGI("Dropping move event because a pointer for a different device is already active "
2044 "in display %" PRId32,
2045 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002046 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002047 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002048 switchedDevice = false;
2049 wrongDevice = true;
2050 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002051 }
2052
2053 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2054 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2055
Garfield Tan00f511d2019-06-12 16:55:40 -07002056 int32_t x;
2057 int32_t y;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002058 const int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07002059 // Always dispatch mouse events to cursor position.
2060 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002061 x = int32_t(entry.xCursorPosition);
2062 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07002063 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002064 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
2065 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07002066 }
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002067 const bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Prabir Pradhand65552b2021-10-07 11:23:50 -07002068 const bool isStylus = isPointerFromStylus(entry, pointerIndex);
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002069 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
Prabir Pradhand65552b2021-10-07 11:23:50 -07002070 isStylus, isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00002071
Michael Wrightd02c5b62014-02-10 15:10:22 -08002072 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002073 if (newTouchedWindowHandle == nullptr) {
Arthur Hungb3307ee2021-10-14 10:57:37 +00002074 ALOGD("No new touched window at (%" PRId32 ", %" PRId32 ") in display %" PRId32, x, y,
2075 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002076 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002077 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002078 }
2079
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002080 // Figure out whether splitting will be allowed for this window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002081 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002082 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2083 // New window supports splitting, but we should never split mouse events.
2084 isSplit = !isFromMouse;
2085 } else if (isSplit) {
2086 // New window does not support splitting but we have already split events.
2087 // Ignore the new window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002088 newTouchedWindowHandle = nullptr;
2089 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002090 } else {
2091 // No window is touched, so set split to true. This will allow the next pointer down to
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002092 // be delivered to a new window which supports split touch. Pointers from a mouse device
2093 // should never be split.
2094 tempTouchState.split = isSplit = !isFromMouse;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002095 }
2096
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002097 // Update hover state.
Michael Wright3dd60e22019-03-27 22:06:44 +00002098 if (newTouchedWindowHandle != nullptr) {
Garfield Tandf26e862020-07-01 20:18:19 -07002099 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2100 newHoverWindowHandle = nullptr;
2101 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002102 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002103 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002104 }
2105
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002106 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002107 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002108 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002109 // Process the foreground window first so that it is the first to receive the event.
2110 newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002111 }
2112
2113 for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
2114 const WindowInfo& info = *windowHandle->getInfo();
2115
2116 if (info.paused) {
2117 ALOGI("Not sending touch event to %s because it is paused",
2118 windowHandle->getName().c_str());
2119 continue;
2120 }
2121
2122 // Ensure the window has a connection and the connection is responsive
2123 const bool isResponsive = hasResponsiveConnectionLocked(*windowHandle);
2124 if (!isResponsive) {
2125 ALOGW("Not sending touch gesture to %s because it is not responsive",
2126 windowHandle->getName().c_str());
2127 continue;
2128 }
2129
2130 // Drop events that can't be trusted due to occlusion
2131 if (mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2132 TouchOcclusionInfo occlusionInfo =
2133 computeTouchOcclusionInfoLocked(windowHandle, x, y);
2134 if (!isTouchTrustedLocked(occlusionInfo)) {
2135 if (DEBUG_TOUCH_OCCLUSION) {
2136 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2137 for (const auto& log : occlusionInfo.debugInfo) {
2138 ALOGD("%s", log.c_str());
2139 }
2140 }
2141 sendUntrustedTouchCommandLocked(occlusionInfo.obscuringPackage);
2142 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2143 ALOGW("Dropping untrusted touch event due to %s/%d",
2144 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2145 continue;
2146 }
2147 }
2148 }
2149
2150 // Drop touch events if requested by input feature
2151 if (shouldDropInput(entry, windowHandle)) {
2152 continue;
2153 }
2154
2155 // Set target flags.
2156 int32_t targetFlags = InputTarget::FLAG_DISPATCH_AS_IS;
2157
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002158 if (!info.isSpy()) {
2159 // There should only be one new foreground (non-spy) window at this location.
2160 targetFlags |= InputTarget::FLAG_FOREGROUND;
2161 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002162
2163 if (isSplit) {
2164 targetFlags |= InputTarget::FLAG_SPLIT;
2165 }
2166 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
2167 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2168 } else if (isWindowObscuredLocked(windowHandle)) {
2169 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2170 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002171
2172 // Update the temporary touch state.
2173 BitSet32 pointerIds;
2174 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002175 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002176 pointerIds.markBit(pointerId);
2177 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002178
2179 tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002180 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002181
2182 const std::vector<Monitor> newGestureMonitors = isDown
2183 ? selectResponsiveMonitorsLocked(
2184 getValueByKey(mGestureMonitorsByDisplay, displayId))
2185 : std::vector<Monitor>{};
2186
2187 if (newTouchedWindows.empty() && newGestureMonitors.empty() &&
2188 tempTouchState.gestureMonitors.empty()) {
2189 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
2190 "(%d, %d) in display %" PRId32 ".",
2191 x, y, displayId);
2192 injectionResult = InputEventInjectionResult::FAILED;
2193 goto Failed;
Arthur Hung2ea44b92021-11-23 07:42:21 +00002194 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002195
2196 tempTouchState.addGestureMonitors(newGestureMonitors);
2197
Michael Wrightd02c5b62014-02-10 15:10:22 -08002198 } else {
2199 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2200
2201 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002202 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002203 if (DEBUG_FOCUS) {
2204 ALOGD("Dropping event because the pointer is not down or we previously "
2205 "dropped the pointer down event in display %" PRId32,
2206 displayId);
2207 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002208 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002209 goto Failed;
2210 }
2211
arthurhung6d4bed92021-03-17 11:59:33 +08002212 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002213
Michael Wrightd02c5b62014-02-10 15:10:22 -08002214 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002215 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002216 tempTouchState.isSlippery()) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002217 const int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2218 const int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002219
Prabir Pradhand65552b2021-10-07 11:23:50 -07002220 const bool isStylus = isPointerFromStylus(entry, 0 /*pointerIndex*/);
chaviw98318de2021-05-19 16:45:23 -05002221 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002222 tempTouchState.getFirstForegroundWindowHandle();
Prabir Pradhand65552b2021-10-07 11:23:50 -07002223 newTouchedWindowHandle =
2224 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState, isStylus);
Vishnu Nair062a8672021-09-03 16:07:44 -07002225
2226 // Drop touch events if requested by input feature
2227 if (newTouchedWindowHandle != nullptr &&
2228 shouldDropInput(entry, newTouchedWindowHandle)) {
2229 newTouchedWindowHandle = nullptr;
2230 }
2231
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002232 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2233 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002234 if (DEBUG_FOCUS) {
2235 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2236 oldTouchedWindowHandle->getName().c_str(),
2237 newTouchedWindowHandle->getName().c_str(), displayId);
2238 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002239 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002240 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2241 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2242 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002243
2244 // Make a slippery entrance into the new window.
2245 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002246 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002247 }
2248
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002249 int32_t targetFlags =
2250 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002251 if (isSplit) {
2252 targetFlags |= InputTarget::FLAG_SPLIT;
2253 }
2254 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2255 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002256 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2257 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002258 }
2259
2260 BitSet32 pointerIds;
2261 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002262 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002263 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002264 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002265 }
2266 }
2267 }
2268
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002269 // Update dispatching for hover enter and exit.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002270 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002271 // Let the previous window know that the hover sequence is over, unless we already did
2272 // it when dispatching it as is to newTouchedWindowHandle.
Garfield Tandf26e862020-07-01 20:18:19 -07002273 if (mLastHoverWindowHandle != nullptr &&
2274 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2275 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002276 if (DEBUG_HOVER) {
2277 ALOGD("Sending hover exit event to window %s.",
2278 mLastHoverWindowHandle->getName().c_str());
2279 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002280 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2281 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002282 }
2283
Garfield Tandf26e862020-07-01 20:18:19 -07002284 // Let the new window know that the hover sequence is starting, unless we already did it
2285 // when dispatching it as is to newTouchedWindowHandle.
2286 if (newHoverWindowHandle != nullptr &&
2287 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2288 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002289 if (DEBUG_HOVER) {
2290 ALOGD("Sending hover enter event to window %s.",
2291 newHoverWindowHandle->getName().c_str());
2292 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002293 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2294 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2295 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002296 }
2297 }
2298
2299 // Check permission to inject into all touched foreground windows and ensure there
2300 // is at least one touched foreground window.
2301 {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002302 bool haveForegroundOrSpyWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002303 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002304 const bool isForeground =
2305 (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0;
2306 if (touchedWindow.windowHandle->getInfo()->isSpy()) {
2307 haveForegroundOrSpyWindow = true;
2308 LOG_ALWAYS_FATAL_IF(isForeground,
2309 "Spy window cannot be dispatched as a foreground window.");
2310 }
2311 if (isForeground) {
2312 haveForegroundOrSpyWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002313 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002314 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002315 injectionPermission = INJECTION_PERMISSION_DENIED;
2316 goto Failed;
2317 }
2318 }
2319 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002320 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002321 if (!haveForegroundOrSpyWindow && !hasGestureMonitor) {
2322 ALOGI("Dropping event because there is no touched window in display "
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002323 "%" PRId32 " or gesture monitor to receive it.",
2324 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002325 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002326 goto Failed;
2327 }
2328
2329 // Permission granted to injection into all touched foreground windows.
2330 injectionPermission = INJECTION_PERMISSION_GRANTED;
2331 }
2332
2333 // Check whether windows listening for outside touches are owned by the same UID. If it is
2334 // set the policy flag that we will not reveal coordinate information to this window.
2335 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002336 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002337 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002338 if (foregroundWindowHandle) {
2339 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002340 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002341 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002342 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2343 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2344 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002345 InputTarget::FLAG_ZERO_COORDS,
2346 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002347 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002348 }
2349 }
2350 }
2351 }
2352
Michael Wrightd02c5b62014-02-10 15:10:22 -08002353 // If this is the first pointer going down and the touched window has a wallpaper
2354 // then also add the touched wallpaper windows so they are locked in for the duration
2355 // of the touch gesture.
2356 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2357 // engine only supports touch events. We would need to add a mechanism similar
2358 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2359 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002360 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002361 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002362 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
chaviw98318de2021-05-19 16:45:23 -05002363 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002364 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002365 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2366 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002367 if (info->displayId == displayId &&
chaviw98318de2021-05-19 16:45:23 -05002368 windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002369 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002370 .addOrUpdateWindow(windowHandle,
2371 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2372 InputTarget::
2373 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2374 InputTarget::FLAG_DISPATCH_AS_IS,
2375 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002376 }
2377 }
2378 }
2379 }
2380
2381 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002382 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002383
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002384 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002385 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002386 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002387 }
2388
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002389 for (const auto& monitor : tempTouchState.gestureMonitors) {
2390 addMonitoringTargetLocked(monitor, displayId, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002391 }
2392
Michael Wrightd02c5b62014-02-10 15:10:22 -08002393 // Drop the outside or hover touch windows since we will not care about them
2394 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002395 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002396
2397Failed:
2398 // Check injection permission once and for all.
2399 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002400 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002401 injectionPermission = INJECTION_PERMISSION_GRANTED;
2402 } else {
2403 injectionPermission = INJECTION_PERMISSION_DENIED;
2404 }
2405 }
2406
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002407 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2408 return injectionResult;
2409 }
2410
Michael Wrightd02c5b62014-02-10 15:10:22 -08002411 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002412 if (!wrongDevice) {
2413 if (switchedDevice) {
2414 if (DEBUG_FOCUS) {
2415 ALOGD("Conflicting pointer actions: Switched to a different device.");
2416 }
2417 *outConflictingPointerActions = true;
2418 }
2419
2420 if (isHoverAction) {
2421 // Started hovering, therefore no longer down.
2422 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002423 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002424 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2425 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002426 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002427 *outConflictingPointerActions = true;
2428 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002429 tempTouchState.reset();
2430 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2431 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2432 tempTouchState.deviceId = entry.deviceId;
2433 tempTouchState.source = entry.source;
2434 tempTouchState.displayId = displayId;
2435 }
2436 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2437 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2438 // All pointers up or canceled.
2439 tempTouchState.reset();
2440 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2441 // First pointer went down.
2442 if (oldState && oldState->down) {
2443 if (DEBUG_FOCUS) {
2444 ALOGD("Conflicting pointer actions: Down received while already down.");
2445 }
2446 *outConflictingPointerActions = true;
2447 }
2448 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2449 // One pointer went up.
2450 if (isSplit) {
2451 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2452 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002453
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002454 for (size_t i = 0; i < tempTouchState.windows.size();) {
2455 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2456 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2457 touchedWindow.pointerIds.clearBit(pointerId);
2458 if (touchedWindow.pointerIds.isEmpty()) {
2459 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2460 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002461 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002462 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002463 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002464 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002465 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002466 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002467
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002468 // Save changes unless the action was scroll in which case the temporary touch
2469 // state was only valid for this one action.
2470 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2471 if (tempTouchState.displayId >= 0) {
2472 mTouchStatesByDisplay[displayId] = tempTouchState;
2473 } else {
2474 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002475 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002476 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002477
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002478 // Update hover state.
2479 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002480 }
2481
Michael Wrightd02c5b62014-02-10 15:10:22 -08002482 return injectionResult;
2483}
2484
arthurhung6d4bed92021-03-17 11:59:33 +08002485void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07002486 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2487 // have an explicit reason to support it.
2488 constexpr bool isStylus = false;
2489
chaviw98318de2021-05-19 16:45:23 -05002490 const sp<WindowInfoHandle> dropWindow =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002491 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/, isStylus,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002492 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002493 if (dropWindow) {
2494 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002495 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002496 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002497 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002498 }
2499 mDragState.reset();
2500}
2501
2502void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2503 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002504 return;
2505 }
2506
arthurhung6d4bed92021-03-17 11:59:33 +08002507 if (!mDragState->isStartDrag) {
2508 mDragState->isStartDrag = true;
2509 mDragState->isStylusButtonDownAtStart =
2510 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2511 }
2512
arthurhungb89ccb02020-12-30 16:19:01 +08002513 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2514 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2515 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2516 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002517 // Handle the special case : stylus button no longer pressed.
2518 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2519 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2520 finishDragAndDrop(entry.displayId, x, y);
2521 return;
2522 }
2523
Prabir Pradhand65552b2021-10-07 11:23:50 -07002524 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until
2525 // we have an explicit reason to support it.
2526 constexpr bool isStylus = false;
2527
chaviw98318de2021-05-19 16:45:23 -05002528 const sp<WindowInfoHandle> hoverWindowHandle =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002529 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/, isStylus,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002530 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002531 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002532 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2533 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2534 if (mDragState->dragHoverWindowHandle != nullptr) {
2535 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2536 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002537 }
arthurhung6d4bed92021-03-17 11:59:33 +08002538 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002539 }
2540 // enqueue drag location if needed.
2541 if (hoverWindowHandle != nullptr) {
2542 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2543 }
arthurhung6d4bed92021-03-17 11:59:33 +08002544 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2545 finishDragAndDrop(entry.displayId, x, y);
2546 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002547 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002548 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002549 }
2550}
2551
chaviw98318de2021-05-19 16:45:23 -05002552void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002553 int32_t targetFlags, BitSet32 pointerIds,
2554 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002555 std::vector<InputTarget>::iterator it =
2556 std::find_if(inputTargets.begin(), inputTargets.end(),
2557 [&windowHandle](const InputTarget& inputTarget) {
2558 return inputTarget.inputChannel->getConnectionToken() ==
2559 windowHandle->getToken();
2560 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002561
chaviw98318de2021-05-19 16:45:23 -05002562 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002563
2564 if (it == inputTargets.end()) {
2565 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002566 std::shared_ptr<InputChannel> inputChannel =
2567 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002568 if (inputChannel == nullptr) {
2569 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2570 return;
2571 }
2572 inputTarget.inputChannel = inputChannel;
2573 inputTarget.flags = targetFlags;
2574 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002575 const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
2576 if (displayInfoIt != mDisplayInfos.end()) {
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002577 inputTarget.displayTransform = displayInfoIt->second.transform;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002578 } else {
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00002579 ALOGE("DisplayInfo not found for window on display: %d", windowInfo->displayId);
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002580 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002581 inputTargets.push_back(inputTarget);
2582 it = inputTargets.end() - 1;
2583 }
2584
2585 ALOG_ASSERT(it->flags == targetFlags);
2586 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2587
chaviw1ff3d1e2020-07-01 15:53:47 -07002588 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002589}
2590
Michael Wright3dd60e22019-03-27 22:06:44 +00002591void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002592 int32_t displayId) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002593 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2594 mGlobalMonitorsByDisplay.find(displayId);
2595
2596 if (it != mGlobalMonitorsByDisplay.end()) {
2597 const std::vector<Monitor>& monitors = it->second;
2598 for (const Monitor& monitor : monitors) {
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002599 addMonitoringTargetLocked(monitor, displayId, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002600 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002601 }
2602}
2603
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002604void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, int32_t displayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002605 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002606 InputTarget target;
2607 target.inputChannel = monitor.inputChannel;
2608 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002609 ui::Transform t;
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002610 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
Prabir Pradhanb5402b22021-10-04 05:52:50 -07002611 const auto& displayTransform = it->second.transform;
2612 target.displayTransform = displayTransform;
2613 t = displayTransform;
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002614 }
chaviw1ff3d1e2020-07-01 15:53:47 -07002615 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002616 inputTargets.push_back(target);
2617}
2618
chaviw98318de2021-05-19 16:45:23 -05002619bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002620 const InjectionState* injectionState) {
2621 if (injectionState &&
2622 (windowHandle == nullptr ||
2623 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2624 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002625 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002626 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002627 "owned by uid %d",
2628 injectionState->injectorPid, injectionState->injectorUid,
2629 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002630 } else {
2631 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002632 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002633 }
2634 return false;
2635 }
2636 return true;
2637}
2638
Robert Carrc9bf1d32020-04-13 17:21:08 -07002639/**
2640 * Indicate whether one window handle should be considered as obscuring
2641 * another window handle. We only check a few preconditions. Actually
2642 * checking the bounds is left to the caller.
2643 */
chaviw98318de2021-05-19 16:45:23 -05002644static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2645 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002646 // Compare by token so cloned layers aren't counted
2647 if (haveSameToken(windowHandle, otherHandle)) {
2648 return false;
2649 }
2650 auto info = windowHandle->getInfo();
2651 auto otherInfo = otherHandle->getInfo();
2652 if (!otherInfo->visible) {
2653 return false;
chaviw98318de2021-05-19 16:45:23 -05002654 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002655 // Those act as if they were invisible, so we don't need to flag them.
2656 // We do want to potentially flag touchable windows even if they have 0
2657 // opacity, since they can consume touches and alter the effects of the
2658 // user interaction (eg. apps that rely on
2659 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2660 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2661 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002662 } else if (info->ownerUid == otherInfo->ownerUid) {
2663 // If ownerUid is the same we don't generate occlusion events as there
2664 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002665 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002666 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002667 return false;
2668 } else if (otherInfo->displayId != info->displayId) {
2669 return false;
2670 }
2671 return true;
2672}
2673
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002674/**
2675 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2676 * untrusted, one should check:
2677 *
2678 * 1. If result.hasBlockingOcclusion is true.
2679 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2680 * BLOCK_UNTRUSTED.
2681 *
2682 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2683 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2684 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2685 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2686 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2687 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2688 *
2689 * If neither of those is true, then it means the touch can be allowed.
2690 */
2691InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002692 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2693 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002694 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002695 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002696 TouchOcclusionInfo info;
2697 info.hasBlockingOcclusion = false;
2698 info.obscuringOpacity = 0;
2699 info.obscuringUid = -1;
2700 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002701 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002702 if (windowHandle == otherHandle) {
2703 break; // All future windows are below us. Exit early.
2704 }
chaviw98318de2021-05-19 16:45:23 -05002705 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002706 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2707 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002708 if (DEBUG_TOUCH_OCCLUSION) {
2709 info.debugInfo.push_back(
2710 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2711 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002712 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2713 // we perform the checks below to see if the touch can be propagated or not based on the
2714 // window's touch occlusion mode
2715 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2716 info.hasBlockingOcclusion = true;
2717 info.obscuringUid = otherInfo->ownerUid;
2718 info.obscuringPackage = otherInfo->packageName;
2719 break;
2720 }
2721 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2722 uint32_t uid = otherInfo->ownerUid;
2723 float opacity =
2724 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2725 // Given windows A and B:
2726 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2727 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2728 opacityByUid[uid] = opacity;
2729 if (opacity > info.obscuringOpacity) {
2730 info.obscuringOpacity = opacity;
2731 info.obscuringUid = uid;
2732 info.obscuringPackage = otherInfo->packageName;
2733 }
2734 }
2735 }
2736 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002737 if (DEBUG_TOUCH_OCCLUSION) {
2738 info.debugInfo.push_back(
2739 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2740 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002741 return info;
2742}
2743
chaviw98318de2021-05-19 16:45:23 -05002744std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002745 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002746 return StringPrintf(INDENT2
2747 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2748 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2749 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2750 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Dominik Laskowski75788452021-02-09 18:51:25 -08002751 isTouchedWindow ? "[TOUCHED] " : "", ftl::enum_string(info->type).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002752 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002753 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2754 info->frameTop, info->frameRight, info->frameBottom,
2755 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002756 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2757 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2758 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002759}
2760
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002761bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2762 if (occlusionInfo.hasBlockingOcclusion) {
2763 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2764 occlusionInfo.obscuringUid);
2765 return false;
2766 }
2767 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2768 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2769 "%.2f, maximum allowed = %.2f)",
2770 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2771 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2772 return false;
2773 }
2774 return true;
2775}
2776
chaviw98318de2021-05-19 16:45:23 -05002777bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002778 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002779 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002780 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2781 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002782 if (windowHandle == otherHandle) {
2783 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002784 }
chaviw98318de2021-05-19 16:45:23 -05002785 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002786 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002787 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002788 return true;
2789 }
2790 }
2791 return false;
2792}
2793
chaviw98318de2021-05-19 16:45:23 -05002794bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002795 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002796 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2797 const WindowInfo* windowInfo = windowHandle->getInfo();
2798 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002799 if (windowHandle == otherHandle) {
2800 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002801 }
chaviw98318de2021-05-19 16:45:23 -05002802 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002803 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002804 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002805 return true;
2806 }
2807 }
2808 return false;
2809}
2810
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002811std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002812 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002813 if (applicationHandle != nullptr) {
2814 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002815 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002816 } else {
2817 return applicationHandle->getName();
2818 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002819 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002820 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002821 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002822 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002823 }
2824}
2825
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002826void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00002827 if (!isUserActivityEvent(eventEntry)) {
2828 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002829 return;
2830 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002831 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002832 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002833 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002834 const WindowInfo* info = focusedWindowHandle->getInfo();
2835 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002836 if (DEBUG_DISPATCH_CYCLE) {
2837 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2838 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002839 return;
2840 }
2841 }
2842
2843 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002844 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002845 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002846 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2847 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002848 return;
2849 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002850
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002851 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002852 eventType = USER_ACTIVITY_EVENT_TOUCH;
2853 }
2854 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002855 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002856 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002857 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2858 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002859 return;
2860 }
2861 eventType = USER_ACTIVITY_EVENT_BUTTON;
2862 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002863 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002864 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002865 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08002866 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002867 break;
2868 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002869 }
2870
Prabir Pradhancef936d2021-07-21 16:17:52 +00002871 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2872 REQUIRES(mLock) {
2873 scoped_unlock unlock(mLock);
2874 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2875 };
2876 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002877}
2878
2879void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002880 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002881 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002882 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002883 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002884 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002885 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002886 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002887 ATRACE_NAME(message.c_str());
2888 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002889 if (DEBUG_DISPATCH_CYCLE) {
2890 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2891 "globalScaleFactor=%f, pointerIds=0x%x %s",
2892 connection->getInputChannelName().c_str(), inputTarget.flags,
2893 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2894 inputTarget.getPointerInfoString().c_str());
2895 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002896
2897 // Skip this event if the connection status is not normal.
2898 // We don't want to enqueue additional outbound events if the connection is broken.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002899 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002900 if (DEBUG_DISPATCH_CYCLE) {
2901 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002902 connection->getInputChannelName().c_str(),
2903 ftl::enum_string(connection->status).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002904 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002905 return;
2906 }
2907
2908 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002909 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2910 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2911 "Entry type %s should not have FLAG_SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08002912 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002913
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002914 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002915 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002916 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002917 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002918 if (!splitMotionEntry) {
2919 return; // split event was dropped
2920 }
Arthur Hungb3307ee2021-10-14 10:57:37 +00002921 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
2922 std::string reason = std::string("reason=pointer cancel on split window");
2923 android_log_event_list(LOGTAG_INPUT_CANCEL)
2924 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
2925 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002926 if (DEBUG_FOCUS) {
2927 ALOGD("channel '%s' ~ Split motion event.",
2928 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002929 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002930 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002931 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2932 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002933 return;
2934 }
2935 }
2936
2937 // Not splitting. Enqueue dispatch entries for the event as is.
2938 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2939}
2940
2941void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002942 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002943 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002944 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002945 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002946 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002947 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002948 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002949 ATRACE_NAME(message.c_str());
2950 }
2951
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002952 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002953
2954 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002955 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002956 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002957 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002958 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002959 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002960 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002961 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002962 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002963 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002964 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002965 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002966 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002967
2968 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002969 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002970 startDispatchCycleLocked(currentTime, connection);
2971 }
2972}
2973
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002974void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002975 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002976 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002977 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002978 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002979 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2980 connection->getInputChannelName().c_str(),
2981 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002982 ATRACE_NAME(message.c_str());
2983 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002984 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002985 if (!(inputTargetFlags & dispatchMode)) {
2986 return;
2987 }
2988 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2989
2990 // This is a new event.
2991 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002992 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002993 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002994
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002995 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2996 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002997 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002998 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002999 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003000 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003001 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003002 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003003 dispatchEntry->resolvedAction = keyEntry.action;
3004 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003005
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003006 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
3007 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003008 if (DEBUG_DISPATCH_CYCLE) {
3009 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
3010 "event",
3011 connection->getInputChannelName().c_str());
3012 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003013 return; // skip the inconsistent event
3014 }
3015 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003016 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003017
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003018 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003019 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003020 // Assign a default value to dispatchEntry that will never be generated by InputReader,
3021 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
3022 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
3023 static_cast<int32_t>(IdGenerator::Source::OTHER);
3024 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003025 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3026 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
3027 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
3028 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
3029 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
3030 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3031 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
3032 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
3033 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
3034 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
3035 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003036 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003037 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003038 }
3039 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003040 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3041 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003042 if (DEBUG_DISPATCH_CYCLE) {
3043 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
3044 "enter event",
3045 connection->getInputChannelName().c_str());
3046 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003047 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
3048 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003049 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3050 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003051
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003052 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003053 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
3054 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3055 }
3056 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
3057 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3058 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003059
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003060 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
3061 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003062 if (DEBUG_DISPATCH_CYCLE) {
3063 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
3064 "event",
3065 connection->getInputChannelName().c_str());
3066 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003067 return; // skip the inconsistent event
3068 }
3069
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003070 dispatchEntry->resolvedEventId =
3071 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
3072 ? mIdGenerator.nextId()
3073 : motionEntry.id;
3074 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
3075 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3076 ") to MotionEvent(id=0x%" PRIx32 ").",
3077 motionEntry.id, dispatchEntry->resolvedEventId);
3078 ATRACE_NAME(message.c_str());
3079 }
3080
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003081 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3082 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
3083 // Skip reporting pointer down outside focus to the policy.
3084 break;
3085 }
3086
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003087 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003088 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003089
3090 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003091 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003092 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003093 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003094 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3095 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003096 break;
3097 }
Chris Yef59a2f42020-10-16 12:55:26 -07003098 case EventEntry::Type::SENSOR: {
3099 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3100 break;
3101 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003102 case EventEntry::Type::CONFIGURATION_CHANGED:
3103 case EventEntry::Type::DEVICE_RESET: {
3104 LOG_ALWAYS_FATAL("%s events should not go to apps",
Dominik Laskowski75788452021-02-09 18:51:25 -08003105 ftl::enum_string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003106 break;
3107 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003108 }
3109
3110 // Remember that we are waiting for this dispatch to complete.
3111 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003112 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003113 }
3114
3115 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003116 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003117 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003118}
3119
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003120/**
3121 * This function is purely for debugging. It helps us understand where the user interaction
3122 * was taking place. For example, if user is touching launcher, we will see a log that user
3123 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3124 * We will see both launcher and wallpaper in that list.
3125 * Once the interaction with a particular set of connections starts, no new logs will be printed
3126 * until the set of interacted connections changes.
3127 *
3128 * The following items are skipped, to reduce the logspam:
3129 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3130 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3131 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3132 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3133 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003134 */
3135void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3136 const std::vector<InputTarget>& targets) {
3137 // Skip ACTION_UP events, and all events other than keys and motions
3138 if (entry.type == EventEntry::Type::KEY) {
3139 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3140 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3141 return;
3142 }
3143 } else if (entry.type == EventEntry::Type::MOTION) {
3144 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3145 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3146 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3147 return;
3148 }
3149 } else {
3150 return; // Not a key or a motion
3151 }
3152
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003153 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003154 std::vector<sp<Connection>> newConnections;
3155 for (const InputTarget& target : targets) {
3156 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3157 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3158 continue; // Skip windows that receive ACTION_OUTSIDE
3159 }
3160
3161 sp<IBinder> token = target.inputChannel->getConnectionToken();
3162 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003163 if (connection == nullptr) {
3164 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003165 }
3166 newConnectionTokens.insert(std::move(token));
3167 newConnections.emplace_back(connection);
3168 }
3169 if (newConnectionTokens == mInteractionConnectionTokens) {
3170 return; // no change
3171 }
3172 mInteractionConnectionTokens = newConnectionTokens;
3173
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003174 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003175 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003176 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003177 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003178 std::string message = "Interaction with: " + targetList;
3179 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003180 message += "<none>";
3181 }
3182 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3183}
3184
chaviwfd6d3512019-03-25 13:23:49 -07003185void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003186 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003187 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003188 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3189 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003190 return;
3191 }
3192
Vishnu Nairc519ff72021-01-21 08:23:08 -08003193 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003194 if (focusedToken == token) {
3195 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003196 return;
3197 }
3198
Prabir Pradhancef936d2021-07-21 16:17:52 +00003199 auto command = [this, token]() REQUIRES(mLock) {
3200 scoped_unlock unlock(mLock);
3201 mPolicy->onPointerDownOutsideFocus(token);
3202 };
3203 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003204}
3205
3206void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003207 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003208 if (ATRACE_ENABLED()) {
3209 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003210 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003211 ATRACE_NAME(message.c_str());
3212 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003213 if (DEBUG_DISPATCH_CYCLE) {
3214 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3215 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003216
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003217 while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003218 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003219 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003220 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003221 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003222 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003223
3224 // Publish the event.
3225 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003226 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3227 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003228 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003229 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3230 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003231
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003232 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003233 status = connection->inputPublisher
3234 .publishKeyEvent(dispatchEntry->seq,
3235 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3236 keyEntry.source, keyEntry.displayId,
3237 std::move(hmac), dispatchEntry->resolvedAction,
3238 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3239 keyEntry.scanCode, keyEntry.metaState,
3240 keyEntry.repeatCount, keyEntry.downTime,
3241 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003242 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003243 }
3244
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003245 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003246 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003247
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003248 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003249 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003250
chaviw82357092020-01-28 13:13:06 -08003251 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003252 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003253 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3254 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003255 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003256 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3257 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003258 // Don't apply window scale here since we don't want scale to affect raw
3259 // coordinates. The scale will be sent back to the client and applied
3260 // later when requesting relative coordinates.
3261 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3262 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003263 }
3264 usingCoords = scaledCoords;
3265 }
3266 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003267 // We don't want the dispatch target to know.
3268 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003269 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003270 scaledCoords[i].clear();
3271 }
3272 usingCoords = scaledCoords;
3273 }
3274 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003275
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003276 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003277
3278 // Publish the motion event.
3279 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003280 .publishMotionEvent(dispatchEntry->seq,
3281 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003282 motionEntry.deviceId, motionEntry.source,
3283 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003284 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003285 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003286 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003287 motionEntry.edgeFlags, motionEntry.metaState,
3288 motionEntry.buttonState,
3289 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003290 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003291 motionEntry.xPrecision, motionEntry.yPrecision,
3292 motionEntry.xCursorPosition,
3293 motionEntry.yCursorPosition,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003294 dispatchEntry->rawTransform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003295 motionEntry.downTime, motionEntry.eventTime,
3296 motionEntry.pointerCount,
3297 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003298 break;
3299 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003300
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003301 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003302 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003303 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003304 focusEntry.id,
Antonio Kantek3cfec7b2021-11-05 18:26:17 -07003305 focusEntry.hasFocus);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003306 break;
3307 }
3308
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003309 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3310 const TouchModeEntry& touchModeEntry =
3311 static_cast<const TouchModeEntry&>(eventEntry);
3312 status = connection->inputPublisher
3313 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3314 touchModeEntry.inTouchMode);
3315
3316 break;
3317 }
3318
Prabir Pradhan99987712020-11-10 18:43:05 -08003319 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3320 const auto& captureEntry =
3321 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3322 status = connection->inputPublisher
3323 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003324 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003325 break;
3326 }
3327
arthurhungb89ccb02020-12-30 16:19:01 +08003328 case EventEntry::Type::DRAG: {
3329 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3330 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3331 dragEntry.id, dragEntry.x,
3332 dragEntry.y,
3333 dragEntry.isExiting);
3334 break;
3335 }
3336
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003337 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003338 case EventEntry::Type::DEVICE_RESET:
3339 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003340 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003341 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003342 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003343 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003344 }
3345
3346 // Check the result.
3347 if (status) {
3348 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003349 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003350 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003351 "This is unexpected because the wait queue is empty, so the pipe "
3352 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003353 "event to it, status=%s(%d)",
3354 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3355 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003356 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3357 } else {
3358 // Pipe is full and we are waiting for the app to finish process some events
3359 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003360 if (DEBUG_DISPATCH_CYCLE) {
3361 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3362 "waiting for the application to catch up",
3363 connection->getInputChannelName().c_str());
3364 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003365 }
3366 } else {
3367 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003368 "status=%s(%d)",
3369 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3370 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003371 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3372 }
3373 return;
3374 }
3375
3376 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003377 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3378 connection->outboundQueue.end(),
3379 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003380 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003381 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003382 if (connection->responsive) {
3383 mAnrTracker.insert(dispatchEntry->timeoutTime,
3384 connection->inputChannel->getConnectionToken());
3385 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003386 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003387 }
3388}
3389
chaviw09c8d2d2020-08-24 15:48:26 -07003390std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3391 size_t size;
3392 switch (event.type) {
3393 case VerifiedInputEvent::Type::KEY: {
3394 size = sizeof(VerifiedKeyEvent);
3395 break;
3396 }
3397 case VerifiedInputEvent::Type::MOTION: {
3398 size = sizeof(VerifiedMotionEvent);
3399 break;
3400 }
3401 }
3402 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3403 return mHmacKeyManager.sign(start, size);
3404}
3405
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003406const std::array<uint8_t, 32> InputDispatcher::getSignature(
3407 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003408 const int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3409 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003410 // Only sign events up and down events as the purely move events
3411 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003412 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003413 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003414
3415 VerifiedMotionEvent verifiedEvent =
3416 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3417 verifiedEvent.actionMasked = actionMasked;
3418 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3419 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003420}
3421
3422const std::array<uint8_t, 32> InputDispatcher::getSignature(
3423 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3424 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3425 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3426 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003427 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003428}
3429
Michael Wrightd02c5b62014-02-10 15:10:22 -08003430void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003431 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003432 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003433 if (DEBUG_DISPATCH_CYCLE) {
3434 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3435 connection->getInputChannelName().c_str(), seq, toString(handled));
3436 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003437
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003438 if (connection->status == Connection::Status::BROKEN ||
3439 connection->status == Connection::Status::ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003440 return;
3441 }
3442
3443 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003444 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3445 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3446 };
3447 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003448}
3449
3450void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003451 const sp<Connection>& connection,
3452 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003453 if (DEBUG_DISPATCH_CYCLE) {
3454 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3455 connection->getInputChannelName().c_str(), toString(notify));
3456 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003457
3458 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003459 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003460 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003461 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003462 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003463
3464 // The connection appears to be unrecoverably broken.
3465 // Ignore already broken or zombie connections.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003466 if (connection->status == Connection::Status::NORMAL) {
3467 connection->status = Connection::Status::BROKEN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003468
3469 if (notify) {
3470 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003471 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3472 connection->getInputChannelName().c_str());
3473
3474 auto command = [this, connection]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003475 scoped_unlock unlock(mLock);
3476 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3477 };
3478 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003479 }
3480 }
3481}
3482
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003483void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3484 while (!queue.empty()) {
3485 DispatchEntry* dispatchEntry = queue.front();
3486 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003487 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003488 }
3489}
3490
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003491void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003492 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003493 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003494 }
3495 delete dispatchEntry;
3496}
3497
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003498int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3499 std::scoped_lock _l(mLock);
3500 sp<Connection> connection = getConnectionLocked(connectionToken);
3501 if (connection == nullptr) {
3502 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3503 connectionToken.get(), events);
3504 return 0; // remove the callback
3505 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003506
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003507 bool notify;
3508 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3509 if (!(events & ALOOPER_EVENT_INPUT)) {
3510 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3511 "events=0x%x",
3512 connection->getInputChannelName().c_str(), events);
3513 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003514 }
3515
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003516 nsecs_t currentTime = now();
3517 bool gotOne = false;
3518 status_t status = OK;
3519 for (;;) {
3520 Result<InputPublisher::ConsumerResponse> result =
3521 connection->inputPublisher.receiveConsumerResponse();
3522 if (!result.ok()) {
3523 status = result.error().code();
3524 break;
3525 }
3526
3527 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3528 const InputPublisher::Finished& finish =
3529 std::get<InputPublisher::Finished>(*result);
3530 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3531 finish.consumeTime);
3532 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003533 if (shouldReportMetricsForConnection(*connection)) {
3534 const InputPublisher::Timeline& timeline =
3535 std::get<InputPublisher::Timeline>(*result);
3536 mLatencyTracker
3537 .trackGraphicsLatency(timeline.inputEventId,
3538 connection->inputChannel->getConnectionToken(),
3539 std::move(timeline.graphicsTimeline));
3540 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003541 }
3542 gotOne = true;
3543 }
3544 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003545 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003546 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003547 return 1;
3548 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003549 }
3550
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003551 notify = status != DEAD_OBJECT || !connection->monitor;
3552 if (notify) {
3553 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3554 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3555 status);
3556 }
3557 } else {
3558 // Monitor channels are never explicitly unregistered.
3559 // We do it automatically when the remote endpoint is closed so don't warn about them.
3560 const bool stillHaveWindowHandle =
3561 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3562 notify = !connection->monitor && stillHaveWindowHandle;
3563 if (notify) {
3564 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3565 connection->getInputChannelName().c_str(), events);
3566 }
3567 }
3568
3569 // Remove the channel.
3570 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3571 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003572}
3573
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003574void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003575 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003576 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003577 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003578 }
3579}
3580
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003581void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003582 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003583 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3584 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3585}
3586
3587void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3588 const CancelationOptions& options,
3589 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3590 for (const auto& it : monitorsByDisplay) {
3591 const std::vector<Monitor>& monitors = it.second;
3592 for (const Monitor& monitor : monitors) {
3593 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003594 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003595 }
3596}
3597
Michael Wrightd02c5b62014-02-10 15:10:22 -08003598void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003599 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003600 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003601 if (connection == nullptr) {
3602 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003603 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003604
3605 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003606}
3607
3608void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3609 const sp<Connection>& connection, const CancelationOptions& options) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003610 if (connection->status == Connection::Status::BROKEN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003611 return;
3612 }
3613
3614 nsecs_t currentTime = now();
3615
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003616 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003617 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003618
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003619 if (cancelationEvents.empty()) {
3620 return;
3621 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003622 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3623 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3624 "with reality: %s, mode=%d.",
3625 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3626 options.mode);
3627 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003628
Arthur Hungb3307ee2021-10-14 10:57:37 +00003629 std::string reason = std::string("reason=").append(options.reason);
3630 android_log_event_list(LOGTAG_INPUT_CANCEL)
3631 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3632
Svet Ganov5d3bc372020-01-26 23:11:07 -08003633 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003634 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003635 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3636 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003637 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003638 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003639 target.globalScaleFactor = windowInfo->globalScaleFactor;
3640 }
3641 target.inputChannel = connection->inputChannel;
3642 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3643
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003644 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003645 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003646 switch (cancelationEventEntry->type) {
3647 case EventEntry::Type::KEY: {
3648 logOutboundKeyDetails("cancel - ",
3649 static_cast<const KeyEntry&>(*cancelationEventEntry));
3650 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003651 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003652 case EventEntry::Type::MOTION: {
3653 logOutboundMotionDetails("cancel - ",
3654 static_cast<const MotionEntry&>(*cancelationEventEntry));
3655 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003656 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003657 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003658 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003659 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3660 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003661 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08003662 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003663 break;
3664 }
3665 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003666 case EventEntry::Type::DEVICE_RESET:
3667 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003668 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003669 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003670 break;
3671 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003672 }
3673
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003674 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3675 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003676 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003677
3678 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003679}
3680
Svet Ganov5d3bc372020-01-26 23:11:07 -08003681void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3682 const sp<Connection>& connection) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003683 if (connection->status == Connection::Status::BROKEN) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003684 return;
3685 }
3686
3687 nsecs_t currentTime = now();
3688
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003689 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003690 connection->inputState.synthesizePointerDownEvents(currentTime);
3691
3692 if (downEvents.empty()) {
3693 return;
3694 }
3695
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003696 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003697 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3698 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003699 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003700
3701 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003702 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003703 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3704 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003705 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003706 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003707 target.globalScaleFactor = windowInfo->globalScaleFactor;
3708 }
3709 target.inputChannel = connection->inputChannel;
3710 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3711
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003712 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003713 switch (downEventEntry->type) {
3714 case EventEntry::Type::MOTION: {
3715 logOutboundMotionDetails("down - ",
3716 static_cast<const MotionEntry&>(*downEventEntry));
3717 break;
3718 }
3719
3720 case EventEntry::Type::KEY:
3721 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003722 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08003723 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003724 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003725 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003726 case EventEntry::Type::SENSOR:
3727 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003728 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003729 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003730 break;
3731 }
3732 }
3733
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003734 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3735 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003736 }
3737
3738 startDispatchCycleLocked(currentTime, connection);
3739}
3740
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003741std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3742 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003743 ALOG_ASSERT(pointerIds.value != 0);
3744
3745 uint32_t splitPointerIndexMap[MAX_POINTERS];
3746 PointerProperties splitPointerProperties[MAX_POINTERS];
3747 PointerCoords splitPointerCoords[MAX_POINTERS];
3748
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003749 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003750 uint32_t splitPointerCount = 0;
3751
3752 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003753 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003754 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003755 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003756 uint32_t pointerId = uint32_t(pointerProperties.id);
3757 if (pointerIds.hasBit(pointerId)) {
3758 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3759 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3760 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003761 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003762 splitPointerCount += 1;
3763 }
3764 }
3765
3766 if (splitPointerCount != pointerIds.count()) {
3767 // This is bad. We are missing some of the pointers that we expected to deliver.
3768 // Most likely this indicates that we received an ACTION_MOVE events that has
3769 // different pointer ids than we expected based on the previous ACTION_DOWN
3770 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3771 // in this way.
3772 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003773 "we expected there to be %d pointers. This probably means we received "
3774 "a broken sequence of pointer ids from the input device.",
3775 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003776 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003777 }
3778
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003779 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003780 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003781 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3782 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003783 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3784 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003785 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003786 uint32_t pointerId = uint32_t(pointerProperties.id);
3787 if (pointerIds.hasBit(pointerId)) {
3788 if (pointerIds.count() == 1) {
3789 // The first/last pointer went down/up.
3790 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003791 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003792 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3793 ? AMOTION_EVENT_ACTION_CANCEL
3794 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003795 } else {
3796 // A secondary pointer went down/up.
3797 uint32_t splitPointerIndex = 0;
3798 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3799 splitPointerIndex += 1;
3800 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003801 action = maskedAction |
3802 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003803 }
3804 } else {
3805 // An unrelated pointer changed.
3806 action = AMOTION_EVENT_ACTION_MOVE;
3807 }
3808 }
3809
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003810 int32_t newId = mIdGenerator.nextId();
3811 if (ATRACE_ENABLED()) {
3812 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3813 ") to MotionEvent(id=0x%" PRIx32 ").",
3814 originalMotionEntry.id, newId);
3815 ATRACE_NAME(message.c_str());
3816 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003817 std::unique_ptr<MotionEntry> splitMotionEntry =
3818 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3819 originalMotionEntry.deviceId, originalMotionEntry.source,
3820 originalMotionEntry.displayId,
3821 originalMotionEntry.policyFlags, action,
3822 originalMotionEntry.actionButton,
3823 originalMotionEntry.flags, originalMotionEntry.metaState,
3824 originalMotionEntry.buttonState,
3825 originalMotionEntry.classification,
3826 originalMotionEntry.edgeFlags,
3827 originalMotionEntry.xPrecision,
3828 originalMotionEntry.yPrecision,
3829 originalMotionEntry.xCursorPosition,
3830 originalMotionEntry.yCursorPosition,
3831 originalMotionEntry.downTime, splitPointerCount,
Prabir Pradhan5beda762021-12-10 09:30:08 +00003832 splitPointerProperties, splitPointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003833
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003834 if (originalMotionEntry.injectionState) {
3835 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003836 splitMotionEntry->injectionState->refCount += 1;
3837 }
3838
3839 return splitMotionEntry;
3840}
3841
3842void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003843 if (DEBUG_INBOUND_EVENT_DETAILS) {
3844 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3845 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003846
Antonio Kantekf16f2832021-09-28 04:39:20 +00003847 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003849 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003850
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003851 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3852 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3853 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003854 } // release lock
3855
3856 if (needWake) {
3857 mLooper->wake();
3858 }
3859}
3860
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003861/**
3862 * If one of the meta shortcuts is detected, process them here:
3863 * Meta + Backspace -> generate BACK
3864 * Meta + Enter -> generate HOME
3865 * This will potentially overwrite keyCode and metaState.
3866 */
3867void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003868 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003869 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3870 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3871 if (keyCode == AKEYCODE_DEL) {
3872 newKeyCode = AKEYCODE_BACK;
3873 } else if (keyCode == AKEYCODE_ENTER) {
3874 newKeyCode = AKEYCODE_HOME;
3875 }
3876 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003877 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003878 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003879 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003880 keyCode = newKeyCode;
3881 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3882 }
3883 } else if (action == AKEY_EVENT_ACTION_UP) {
3884 // In order to maintain a consistent stream of up and down events, check to see if the key
3885 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3886 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003887 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003888 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003889 auto replacementIt = mReplacedKeys.find(replacement);
3890 if (replacementIt != mReplacedKeys.end()) {
3891 keyCode = replacementIt->second;
3892 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003893 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3894 }
3895 }
3896}
3897
Michael Wrightd02c5b62014-02-10 15:10:22 -08003898void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003899 if (DEBUG_INBOUND_EVENT_DETAILS) {
3900 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3901 "policyFlags=0x%x, action=0x%x, "
3902 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3903 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3904 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3905 args->downTime);
3906 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003907 if (!validateKeyEvent(args->action)) {
3908 return;
3909 }
3910
3911 uint32_t policyFlags = args->policyFlags;
3912 int32_t flags = args->flags;
3913 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003914 // InputDispatcher tracks and generates key repeats on behalf of
3915 // whatever notifies it, so repeatCount should always be set to 0
3916 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003917 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3918 policyFlags |= POLICY_FLAG_VIRTUAL;
3919 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3920 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003921 if (policyFlags & POLICY_FLAG_FUNCTION) {
3922 metaState |= AMETA_FUNCTION_ON;
3923 }
3924
3925 policyFlags |= POLICY_FLAG_TRUSTED;
3926
Michael Wright78f24442014-08-06 15:55:28 -07003927 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003928 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003929
Michael Wrightd02c5b62014-02-10 15:10:22 -08003930 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003931 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003932 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3933 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003934
Michael Wright2b3c3302018-03-02 17:19:13 +00003935 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003936 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003937 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3938 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003939 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003940 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003941
Antonio Kantekf16f2832021-09-28 04:39:20 +00003942 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003943 { // acquire lock
3944 mLock.lock();
3945
3946 if (shouldSendKeyToInputFilterLocked(args)) {
3947 mLock.unlock();
3948
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003949 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003950 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3951 return; // event was consumed by the filter
3952 }
3953
3954 mLock.lock();
3955 }
3956
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003957 std::unique_ptr<KeyEntry> newEntry =
3958 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3959 args->displayId, policyFlags, args->action, flags,
3960 keyCode, args->scanCode, metaState, repeatCount,
3961 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003963 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003964 mLock.unlock();
3965 } // release lock
3966
3967 if (needWake) {
3968 mLooper->wake();
3969 }
3970}
3971
3972bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3973 return mInputFilterEnabled;
3974}
3975
3976void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003977 if (DEBUG_INBOUND_EVENT_DETAILS) {
3978 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3979 "displayId=%" PRId32 ", policyFlags=0x%x, "
3980 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3981 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
3982 "yCursorPosition=%f, downTime=%" PRId64,
3983 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3984 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3985 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3986 args->xCursorPosition, args->yCursorPosition, args->downTime);
3987 for (uint32_t i = 0; i < args->pointerCount; i++) {
3988 ALOGD(" Pointer %d: id=%d, toolType=%d, "
3989 "x=%f, y=%f, pressure=%f, size=%f, "
3990 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3991 "orientation=%f",
3992 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3993 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3994 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3995 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3996 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3997 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3998 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3999 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
4000 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
4001 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
4002 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004003 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004004 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
4005 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004006 return;
4007 }
4008
4009 uint32_t policyFlags = args->policyFlags;
4010 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004011
4012 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08004013 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004014 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4015 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004016 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004017 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004018
Antonio Kantekf16f2832021-09-28 04:39:20 +00004019 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004020 { // acquire lock
4021 mLock.lock();
4022
4023 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004024 ui::Transform displayTransform;
4025 if (const auto it = mDisplayInfos.find(args->displayId); it != mDisplayInfos.end()) {
4026 displayTransform = it->second.transform;
4027 }
4028
Michael Wrightd02c5b62014-02-10 15:10:22 -08004029 mLock.unlock();
4030
4031 MotionEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08004032 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
4033 args->action, args->actionButton, args->flags, args->edgeFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07004034 args->metaState, args->buttonState, args->classification,
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004035 displayTransform, args->xPrecision, args->yPrecision,
4036 args->xCursorPosition, args->yCursorPosition, displayTransform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07004037 args->downTime, args->eventTime, args->pointerCount,
4038 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004039
4040 policyFlags |= POLICY_FLAG_FILTERED;
4041 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
4042 return; // event was consumed by the filter
4043 }
4044
4045 mLock.lock();
4046 }
4047
4048 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004049 std::unique_ptr<MotionEntry> newEntry =
4050 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
4051 args->source, args->displayId, policyFlags,
4052 args->action, args->actionButton, args->flags,
4053 args->metaState, args->buttonState,
4054 args->classification, args->edgeFlags,
4055 args->xPrecision, args->yPrecision,
4056 args->xCursorPosition, args->yCursorPosition,
4057 args->downTime, args->pointerCount,
Prabir Pradhan5beda762021-12-10 09:30:08 +00004058 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004059
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004060 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4061 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
4062 !mInputFilterEnabled) {
4063 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
4064 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
4065 }
4066
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004067 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004068 mLock.unlock();
4069 } // release lock
4070
4071 if (needWake) {
4072 mLooper->wake();
4073 }
4074}
4075
Chris Yef59a2f42020-10-16 12:55:26 -07004076void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004077 if (DEBUG_INBOUND_EVENT_DETAILS) {
4078 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4079 " sensorType=%s",
4080 args->id, args->eventTime, args->deviceId, args->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08004081 ftl::enum_string(args->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004082 }
Chris Yef59a2f42020-10-16 12:55:26 -07004083
Antonio Kantekf16f2832021-09-28 04:39:20 +00004084 bool needWake = false;
Chris Yef59a2f42020-10-16 12:55:26 -07004085 { // acquire lock
4086 mLock.lock();
4087
4088 // Just enqueue a new sensor event.
4089 std::unique_ptr<SensorEntry> newEntry =
4090 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
4091 args->source, 0 /* policyFlags*/, args->hwTimestamp,
4092 args->sensorType, args->accuracy,
4093 args->accuracyChanged, args->values);
4094
4095 needWake = enqueueInboundEventLocked(std::move(newEntry));
4096 mLock.unlock();
4097 } // release lock
4098
4099 if (needWake) {
4100 mLooper->wake();
4101 }
4102}
4103
Chris Yefb552902021-02-03 17:18:37 -08004104void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004105 if (DEBUG_INBOUND_EVENT_DETAILS) {
4106 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
4107 args->deviceId, args->isOn);
4108 }
Chris Yefb552902021-02-03 17:18:37 -08004109 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
4110}
4111
Michael Wrightd02c5b62014-02-10 15:10:22 -08004112bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08004113 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004114}
4115
4116void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004117 if (DEBUG_INBOUND_EVENT_DETAILS) {
4118 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4119 "switchMask=0x%08x",
4120 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
4121 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004122
4123 uint32_t policyFlags = args->policyFlags;
4124 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004125 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004126}
4127
4128void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004129 if (DEBUG_INBOUND_EVENT_DETAILS) {
4130 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
4131 args->deviceId);
4132 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004133
Antonio Kantekf16f2832021-09-28 04:39:20 +00004134 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004135 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004136 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004137
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004138 std::unique_ptr<DeviceResetEntry> newEntry =
4139 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
4140 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004141 } // release lock
4142
4143 if (needWake) {
4144 mLooper->wake();
4145 }
4146}
4147
Prabir Pradhan7e186182020-11-10 13:56:45 -08004148void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004149 if (DEBUG_INBOUND_EVENT_DETAILS) {
4150 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004151 args->request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004152 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004153
Antonio Kantekf16f2832021-09-28 04:39:20 +00004154 bool needWake = false;
Prabir Pradhan99987712020-11-10 18:43:05 -08004155 { // acquire lock
4156 std::scoped_lock _l(mLock);
4157 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004158 args->request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004159 needWake = enqueueInboundEventLocked(std::move(entry));
4160 } // release lock
4161
4162 if (needWake) {
4163 mLooper->wake();
4164 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004165}
4166
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004167InputEventInjectionResult InputDispatcher::injectInputEvent(
4168 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4169 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004170 if (DEBUG_INBOUND_EVENT_DETAILS) {
4171 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
4172 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4173 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
4174 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004175 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004176
4177 policyFlags |= POLICY_FLAG_INJECTED;
4178 if (hasInjectionPermission(injectorPid, injectorUid)) {
4179 policyFlags |= POLICY_FLAG_TRUSTED;
4180 }
4181
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004182 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004183 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4184 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4185 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4186 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4187 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004188 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004189 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004190 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004191 }
4192
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004193 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004194 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004195 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004196 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4197 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004198 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004199 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004200 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004201
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004202 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004203 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4204 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4205 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004206 int32_t keyCode = incomingKey.getKeyCode();
4207 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004208 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004209 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004210 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004211 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004212 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4213 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4214 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004215
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004216 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4217 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004218 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004219
4220 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4221 android::base::Timer t;
4222 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4223 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4224 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4225 std::to_string(t.duration().count()).c_str());
4226 }
4227 }
4228
4229 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004230 std::unique_ptr<KeyEntry> injectedEntry =
4231 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004232 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004233 incomingKey.getDisplayId(), policyFlags, action,
4234 flags, keyCode, incomingKey.getScanCode(), metaState,
4235 incomingKey.getRepeatCount(),
4236 incomingKey.getDownTime());
4237 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004238 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004239 }
4240
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004241 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004242 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004243 const int32_t action = motionEvent.getAction();
4244 const bool isPointerEvent =
4245 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4246 // If a pointer event has no displayId specified, inject it to the default display.
4247 const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
4248 ? ADISPLAY_ID_DEFAULT
4249 : event->getDisplayId();
4250 const size_t pointerCount = motionEvent.getPointerCount();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004251 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004252 const int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004253 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004254 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004255 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004256 }
4257
4258 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004259 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004260 android::base::Timer t;
4261 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4262 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4263 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4264 std::to_string(t.duration().count()).c_str());
4265 }
4266 }
4267
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004268 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4269 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4270 }
4271
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004272 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004273 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4274 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004275 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004276 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4277 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004278 displayId, policyFlags, action, actionButton,
4279 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004280 motionEvent.getButtonState(),
4281 motionEvent.getClassification(),
4282 motionEvent.getEdgeFlags(),
4283 motionEvent.getXPrecision(),
4284 motionEvent.getYPrecision(),
4285 motionEvent.getRawXCursorPosition(),
4286 motionEvent.getRawYCursorPosition(),
4287 motionEvent.getDownTime(), uint32_t(pointerCount),
Prabir Pradhan5beda762021-12-10 09:30:08 +00004288 pointerProperties, samplePointerCoords);
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004289 transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004290 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004291 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004292 sampleEventTimes += 1;
4293 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004294 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004295 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4296 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004297 displayId, policyFlags, action, actionButton,
4298 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004299 motionEvent.getButtonState(),
4300 motionEvent.getClassification(),
4301 motionEvent.getEdgeFlags(),
4302 motionEvent.getXPrecision(),
4303 motionEvent.getYPrecision(),
4304 motionEvent.getRawXCursorPosition(),
4305 motionEvent.getRawYCursorPosition(),
4306 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004307 uint32_t(pointerCount), pointerProperties,
Prabir Pradhan5beda762021-12-10 09:30:08 +00004308 samplePointerCoords);
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004309 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
4310 motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004311 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004312 }
4313 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004314 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004315
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004316 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004317 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004318 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004319 }
4320
4321 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004322 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004323 injectionState->injectionIsAsync = true;
4324 }
4325
4326 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004327 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004328
4329 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004330 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004331 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004332 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004333 }
4334
4335 mLock.unlock();
4336
4337 if (needWake) {
4338 mLooper->wake();
4339 }
4340
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004341 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004342 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004343 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004344
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004345 if (syncMode == InputEventInjectionSync::NONE) {
4346 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004347 } else {
4348 for (;;) {
4349 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004350 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004351 break;
4352 }
4353
4354 nsecs_t remainingTimeout = endTime - now();
4355 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004356 if (DEBUG_INJECTION) {
4357 ALOGD("injectInputEvent - Timed out waiting for injection result "
4358 "to become available.");
4359 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004360 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004361 break;
4362 }
4363
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004364 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004365 }
4366
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004367 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4368 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004369 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004370 if (DEBUG_INJECTION) {
4371 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4372 injectionState->pendingForegroundDispatches);
4373 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004374 nsecs_t remainingTimeout = endTime - now();
4375 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004376 if (DEBUG_INJECTION) {
4377 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4378 "dispatches to finish.");
4379 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004380 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004381 break;
4382 }
4383
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004384 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004385 }
4386 }
4387 }
4388
4389 injectionState->release();
4390 } // release lock
4391
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004392 if (DEBUG_INJECTION) {
4393 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
4394 injectionResult, injectorPid, injectorUid);
4395 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004396
4397 return injectionResult;
4398}
4399
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004400std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004401 std::array<uint8_t, 32> calculatedHmac;
4402 std::unique_ptr<VerifiedInputEvent> result;
4403 switch (event.getType()) {
4404 case AINPUT_EVENT_TYPE_KEY: {
4405 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4406 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4407 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004408 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004409 break;
4410 }
4411 case AINPUT_EVENT_TYPE_MOTION: {
4412 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4413 VerifiedMotionEvent verifiedMotionEvent =
4414 verifiedMotionEventFromMotionEvent(motionEvent);
4415 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004416 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004417 break;
4418 }
4419 default: {
4420 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4421 return nullptr;
4422 }
4423 }
4424 if (calculatedHmac == INVALID_HMAC) {
4425 return nullptr;
4426 }
4427 if (calculatedHmac != event.getHmac()) {
4428 return nullptr;
4429 }
4430 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004431}
4432
Michael Wrightd02c5b62014-02-10 15:10:22 -08004433bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004434 return injectorUid == 0 ||
4435 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004436}
4437
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004438void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004439 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004440 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004441 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004442 if (DEBUG_INJECTION) {
4443 ALOGD("Setting input event injection result to %d. "
4444 "injectorPid=%d, injectorUid=%d",
4445 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
4446 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004447
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004448 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004449 // Log the outcome since the injector did not wait for the injection result.
4450 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004451 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004452 ALOGV("Asynchronous input event injection succeeded.");
4453 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004454 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004455 ALOGW("Asynchronous input event injection failed.");
4456 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004457 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004458 ALOGW("Asynchronous input event injection permission denied.");
4459 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004460 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004461 ALOGW("Asynchronous input event injection timed out.");
4462 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004463 case InputEventInjectionResult::PENDING:
4464 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4465 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004466 }
4467 }
4468
4469 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004470 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004471 }
4472}
4473
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004474void InputDispatcher::transformMotionEntryForInjectionLocked(
4475 MotionEntry& entry, const ui::Transform& injectedTransform) const {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004476 // Input injection works in the logical display coordinate space, but the input pipeline works
4477 // display space, so we need to transform the injected events accordingly.
4478 const auto it = mDisplayInfos.find(entry.displayId);
4479 if (it == mDisplayInfos.end()) return;
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004480 const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004481
4482 for (uint32_t i = 0; i < entry.pointerCount; i++) {
4483 PointerCoords& pc = entry.pointerCoords[i];
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004484 // Make a copy of the injected coords. We cannot change them in place because some of them
4485 // are interdependent (for example, X coordinate might depend on the Y coordinate).
4486 PointerCoords injectedCoords = entry.pointerCoords[i];
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004487
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004488 BitSet64 bits(injectedCoords.bits);
4489 while (!bits.isEmpty()) {
4490 const auto axis = static_cast<int32_t>(bits.clearFirstMarkedBit());
4491 const float value =
4492 MotionEvent::calculateTransformedAxisValue(axis, entry.source,
4493 transformToDisplay, injectedCoords);
4494 pc.setAxisValue(axis, value);
4495 }
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004496 }
4497}
4498
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004499void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4500 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004501 if (injectionState) {
4502 injectionState->pendingForegroundDispatches += 1;
4503 }
4504}
4505
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004506void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4507 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004508 if (injectionState) {
4509 injectionState->pendingForegroundDispatches -= 1;
4510
4511 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004512 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004513 }
4514 }
4515}
4516
chaviw98318de2021-05-19 16:45:23 -05004517const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004518 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004519 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004520 auto it = mWindowHandlesByDisplay.find(displayId);
4521 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004522}
4523
chaviw98318de2021-05-19 16:45:23 -05004524sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004525 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004526 if (windowHandleToken == nullptr) {
4527 return nullptr;
4528 }
4529
Arthur Hungb92218b2018-08-14 12:00:21 +08004530 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004531 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4532 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004533 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004534 return windowHandle;
4535 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004536 }
4537 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004538 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004539}
4540
chaviw98318de2021-05-19 16:45:23 -05004541sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4542 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004543 if (windowHandleToken == nullptr) {
4544 return nullptr;
4545 }
4546
chaviw98318de2021-05-19 16:45:23 -05004547 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004548 if (windowHandle->getToken() == windowHandleToken) {
4549 return windowHandle;
4550 }
4551 }
4552 return nullptr;
4553}
4554
chaviw98318de2021-05-19 16:45:23 -05004555sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4556 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004557 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004558 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4559 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004560 if (handle->getId() == windowHandle->getId() &&
4561 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004562 if (windowHandle->getInfo()->displayId != it.first) {
4563 ALOGE("Found window %s in display %" PRId32
4564 ", but it should belong to display %" PRId32,
4565 windowHandle->getName().c_str(), it.first,
4566 windowHandle->getInfo()->displayId);
4567 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004568 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004569 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004570 }
4571 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004572 return nullptr;
4573}
4574
chaviw98318de2021-05-19 16:45:23 -05004575sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004576 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4577 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004578}
4579
chaviw98318de2021-05-19 16:45:23 -05004580bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004581 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4582 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004583 windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004584 if (connection != nullptr && noInputChannel) {
4585 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4586 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4587 return false;
4588 }
4589
4590 if (connection == nullptr) {
4591 if (!noInputChannel) {
4592 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4593 }
4594 return false;
4595 }
4596 if (!connection->responsive) {
4597 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4598 return false;
4599 }
4600 return true;
4601}
4602
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004603std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4604 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004605 auto connectionIt = mConnectionsByToken.find(token);
4606 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004607 return nullptr;
4608 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004609 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004610}
4611
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004612void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004613 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4614 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004615 // Remove all handles on a display if there are no windows left.
4616 mWindowHandlesByDisplay.erase(displayId);
4617 return;
4618 }
4619
4620 // Since we compare the pointer of input window handles across window updates, we need
4621 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004622 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4623 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4624 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004625 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004626 }
4627
chaviw98318de2021-05-19 16:45:23 -05004628 std::vector<sp<WindowInfoHandle>> newHandles;
4629 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05004630 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004631 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004632 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004633 info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
4634 const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
4635 !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004636 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004637 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004638 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004639 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004640 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004641 }
4642
4643 if (info->displayId != displayId) {
4644 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4645 handle->getName().c_str(), displayId, info->displayId);
4646 continue;
4647 }
4648
Robert Carredd13602020-04-13 17:24:34 -07004649 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4650 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004651 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004652 oldHandle->updateFrom(handle);
4653 newHandles.push_back(oldHandle);
4654 } else {
4655 newHandles.push_back(handle);
4656 }
4657 }
4658
4659 // Insert or replace
4660 mWindowHandlesByDisplay[displayId] = newHandles;
4661}
4662
Arthur Hung72d8dc32020-03-28 00:48:39 +00004663void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004664 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07004665 // TODO(b/198444055): Remove setInputWindows from InputDispatcher.
Arthur Hung72d8dc32020-03-28 00:48:39 +00004666 { // acquire lock
4667 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004668 for (const auto& [displayId, handles] : handlesPerDisplay) {
4669 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004670 }
4671 }
4672 // Wake up poll loop since it may need to make new input dispatching choices.
4673 mLooper->wake();
4674}
4675
Arthur Hungb92218b2018-08-14 12:00:21 +08004676/**
4677 * Called from InputManagerService, update window handle list by displayId that can receive input.
4678 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4679 * If set an empty list, remove all handles from the specific display.
4680 * For focused handle, check if need to change and send a cancel event to previous one.
4681 * For removed handle, check if need to send a cancel event if already in touch.
4682 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004683void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004684 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004685 if (DEBUG_FOCUS) {
4686 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004687 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004688 windowList += iwh->getName() + " ";
4689 }
4690 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4691 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004692
Prabir Pradhand65552b2021-10-07 11:23:50 -07004693 // Check preconditions for new input windows
chaviw98318de2021-05-19 16:45:23 -05004694 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07004695 const WindowInfo& info = *window->getInfo();
4696
4697 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4698 const bool noInputWindow = info.inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004699 if (noInputWindow && window->getToken() != nullptr) {
4700 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4701 window->getName().c_str());
4702 window->releaseChannel();
4703 }
Prabir Pradhand65552b2021-10-07 11:23:50 -07004704
Prabir Pradhan5c85e052021-12-22 02:27:12 -08004705 // Ensure all spy windows are trusted overlays
4706 LOG_ALWAYS_FATAL_IF(info.isSpy() && !info.trustedOverlay,
4707 "%s has feature SPY, but is not a trusted overlay.",
4708 window->getName().c_str());
4709
Prabir Pradhand65552b2021-10-07 11:23:50 -07004710 // Ensure all stylus interceptors are trusted overlays
4711 LOG_ALWAYS_FATAL_IF(info.interceptsStylus() && !info.trustedOverlay,
4712 "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
4713 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004714 }
4715
Arthur Hung72d8dc32020-03-28 00:48:39 +00004716 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004717 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004718
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004719 // Save the old windows' orientation by ID before it gets updated.
4720 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004721 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004722 oldWindowOrientations.emplace(handle->getId(),
4723 handle->getInfo()->transform.getOrientation());
4724 }
4725
chaviw98318de2021-05-19 16:45:23 -05004726 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004727
chaviw98318de2021-05-19 16:45:23 -05004728 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004729 if (mLastHoverWindowHandle &&
4730 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4731 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004732 mLastHoverWindowHandle = nullptr;
4733 }
4734
Vishnu Nairc519ff72021-01-21 08:23:08 -08004735 std::optional<FocusResolver::FocusChanges> changes =
4736 mFocusResolver.setInputWindows(displayId, windowHandles);
4737 if (changes) {
4738 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004739 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004740
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004741 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4742 mTouchStatesByDisplay.find(displayId);
4743 if (stateIt != mTouchStatesByDisplay.end()) {
4744 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004745 for (size_t i = 0; i < state.windows.size();) {
4746 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004747 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004748 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004749 ALOGD("Touched window was removed: %s in display %" PRId32,
4750 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004751 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004752 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004753 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4754 if (touchedInputChannel != nullptr) {
4755 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4756 "touched window was removed");
4757 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004758 // Since we are about to drop the touch, cancel the events for the wallpaper as
4759 // well.
4760 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND &&
4761 touchedWindow.windowHandle->getInfo()->hasWallpaper) {
4762 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
4763 if (wallpaper != nullptr) {
4764 sp<Connection> wallpaperConnection =
4765 getConnectionLocked(wallpaper->getToken());
Siarhei Vishniakou2b030972021-11-18 10:01:27 -08004766 if (wallpaperConnection != nullptr) {
4767 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection,
4768 options);
4769 }
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004770 }
4771 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004772 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004773 state.windows.erase(state.windows.begin() + i);
4774 } else {
4775 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004776 }
4777 }
arthurhungb89ccb02020-12-30 16:19:01 +08004778
arthurhung6d4bed92021-03-17 11:59:33 +08004779 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004780 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004781 if (mDragState &&
4782 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004783 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004784 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004785 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004786 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004787
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00004788 // Determine if the orientation of any of the input windows have changed, and cancel all
4789 // pointer events if necessary.
4790 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4791 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
4792 if (newWindowHandle != nullptr &&
4793 newWindowHandle->getInfo()->transform.getOrientation() !=
4794 oldWindowOrientations[oldWindowHandle->getId()]) {
4795 std::shared_ptr<InputChannel> inputChannel =
4796 getInputChannelLocked(newWindowHandle->getToken());
4797 if (inputChannel != nullptr) {
4798 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4799 "touched window's orientation changed");
4800 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004801 }
4802 }
4803 }
4804
Arthur Hung72d8dc32020-03-28 00:48:39 +00004805 // Release information for windows that are no longer present.
4806 // This ensures that unused input channels are released promptly.
4807 // Otherwise, they might stick around until the window handle is destroyed
4808 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004809 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004810 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004811 if (DEBUG_FOCUS) {
4812 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004813 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004814 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004815 // To avoid making too many calls into the compat framework, only
4816 // check for window flags when windows are going away.
4817 // TODO(b/157929241) : delete this. This is only needed temporarily
4818 // in order to gather some data about the flag usage
chaviw98318de2021-05-19 16:45:23 -05004819 if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004820 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4821 oldWindowHandle->getName().c_str());
4822 if (mCompatService != nullptr) {
4823 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4824 oldWindowHandle->getInfo()->ownerUid);
4825 }
4826 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004827 }
chaviw291d88a2019-02-14 10:33:58 -08004828 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004829}
4830
4831void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004832 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004833 if (DEBUG_FOCUS) {
4834 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4835 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4836 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004837 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004838 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004839 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004840 } // release lock
4841
4842 // Wake up poll loop since it may need to make new input dispatching choices.
4843 mLooper->wake();
4844}
4845
Vishnu Nair599f1412021-06-21 10:39:58 -07004846void InputDispatcher::setFocusedApplicationLocked(
4847 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4848 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4849 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4850
4851 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4852 return; // This application is already focused. No need to wake up or change anything.
4853 }
4854
4855 // Set the new application handle.
4856 if (inputApplicationHandle != nullptr) {
4857 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4858 } else {
4859 mFocusedApplicationHandlesByDisplay.erase(displayId);
4860 }
4861
4862 // No matter what the old focused application was, stop waiting on it because it is
4863 // no longer focused.
4864 resetNoFocusedWindowTimeoutLocked();
4865}
4866
Tiger Huang721e26f2018-07-24 22:26:19 +08004867/**
4868 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4869 * the display not specified.
4870 *
4871 * We track any unreleased events for each window. If a window loses the ability to receive the
4872 * released event, we will send a cancel event to it. So when the focused display is changed, we
4873 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4874 * display. The display-specified events won't be affected.
4875 */
4876void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004877 if (DEBUG_FOCUS) {
4878 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4879 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004880 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004881 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004882
4883 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004884 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004885 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004886 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004887 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004888 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004889 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004890 CancelationOptions
4891 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4892 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004893 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004894 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4895 }
4896 }
4897 mFocusedDisplayId = displayId;
4898
Chris Ye3c2d6f52020-08-09 10:39:48 -07004899 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004900 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004901 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004902
Vishnu Nairad321cd2020-08-20 16:40:21 -07004903 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004904 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004905 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004906 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004907 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004908 }
4909 }
4910 }
4911
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004912 if (DEBUG_FOCUS) {
4913 logDispatchStateLocked();
4914 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004915 } // release lock
4916
4917 // Wake up poll loop since it may need to make new input dispatching choices.
4918 mLooper->wake();
4919}
4920
Michael Wrightd02c5b62014-02-10 15:10:22 -08004921void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004922 if (DEBUG_FOCUS) {
4923 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4924 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925
4926 bool changed;
4927 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004928 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004929
4930 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4931 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004932 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004933 }
4934
4935 if (mDispatchEnabled && !enabled) {
4936 resetAndDropEverythingLocked("dispatcher is being disabled");
4937 }
4938
4939 mDispatchEnabled = enabled;
4940 mDispatchFrozen = frozen;
4941 changed = true;
4942 } else {
4943 changed = false;
4944 }
4945
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004946 if (DEBUG_FOCUS) {
4947 logDispatchStateLocked();
4948 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004949 } // release lock
4950
4951 if (changed) {
4952 // Wake up poll loop since it may need to make new input dispatching choices.
4953 mLooper->wake();
4954 }
4955}
4956
4957void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004958 if (DEBUG_FOCUS) {
4959 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4960 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004961
4962 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004963 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004964
4965 if (mInputFilterEnabled == enabled) {
4966 return;
4967 }
4968
4969 mInputFilterEnabled = enabled;
4970 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4971 } // release lock
4972
4973 // Wake up poll loop since there might be work to do to drop everything.
4974 mLooper->wake();
4975}
4976
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004977void InputDispatcher::setInTouchMode(bool inTouchMode) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00004978 bool needWake = false;
4979 {
4980 std::scoped_lock lock(mLock);
4981 if (mInTouchMode == inTouchMode) {
4982 return;
4983 }
4984 if (DEBUG_TOUCH_MODE) {
4985 ALOGD("Request to change touch mode from %s to %s", toString(mInTouchMode),
4986 toString(inTouchMode));
4987 // TODO(b/198487159): Also print the current last interacted apps.
4988 }
4989
4990 // TODO(b/198499018): Store touch mode per display.
4991 mInTouchMode = inTouchMode;
4992
4993 // TODO(b/198487159): Enforce that only last interacted apps can change touch mode.
4994 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode);
4995 needWake = enqueueInboundEventLocked(std::move(entry));
4996 } // release lock
4997
4998 if (needWake) {
4999 mLooper->wake();
5000 }
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08005001}
5002
Bernardo Rufinoea97d182020-08-19 14:43:14 +01005003void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
5004 if (opacity < 0 || opacity > 1) {
5005 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
5006 return;
5007 }
5008
5009 std::scoped_lock lock(mLock);
5010 mMaximumObscuringOpacityForTouch = opacity;
5011}
5012
5013void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
5014 std::scoped_lock lock(mLock);
5015 mBlockUntrustedTouchesMode = mode;
5016}
5017
Arthur Hungabbb9d82021-09-01 14:52:30 +00005018std::pair<TouchState*, TouchedWindow*> InputDispatcher::findTouchStateAndWindowLocked(
5019 const sp<IBinder>& token) {
5020 for (auto& [displayId, state] : mTouchStatesByDisplay) {
5021 for (TouchedWindow& w : state.windows) {
5022 if (w.windowHandle->getToken() == token) {
5023 return std::make_pair(&state, &w);
5024 }
5025 }
5026 }
5027 return std::make_pair(nullptr, nullptr);
5028}
5029
arthurhungb89ccb02020-12-30 16:19:01 +08005030bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5031 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08005032 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005033 if (DEBUG_FOCUS) {
5034 ALOGD("Trivial transfer to same window.");
5035 }
chaviwfbe5d9c2018-12-26 12:23:37 -08005036 return true;
5037 }
5038
Michael Wrightd02c5b62014-02-10 15:10:22 -08005039 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005040 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005041
Arthur Hungabbb9d82021-09-01 14:52:30 +00005042 // Find the target touch state and touched window by fromToken.
5043 auto [state, touchedWindow] = findTouchStateAndWindowLocked(fromToken);
5044 if (state == nullptr || touchedWindow == nullptr) {
5045 ALOGD("Focus transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005046 return false;
5047 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00005048
5049 const int32_t displayId = state->displayId;
5050 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
5051 if (toWindowHandle == nullptr) {
5052 ALOGW("Cannot transfer focus because to window not found.");
5053 return false;
5054 }
5055
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005056 if (DEBUG_FOCUS) {
5057 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00005058 touchedWindow->windowHandle->getName().c_str(),
5059 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005060 }
5061
Arthur Hungabbb9d82021-09-01 14:52:30 +00005062 // Erase old window.
5063 int32_t oldTargetFlags = touchedWindow->targetFlags;
5064 BitSet32 pointerIds = touchedWindow->pointerIds;
5065 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005066
Arthur Hungabbb9d82021-09-01 14:52:30 +00005067 // Add new window.
5068 int32_t newTargetFlags = oldTargetFlags &
5069 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
5070 InputTarget::FLAG_DISPATCH_AS_IS);
5071 state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005072
Arthur Hungabbb9d82021-09-01 14:52:30 +00005073 // Store the dragging window.
5074 if (isDragDrop) {
5075 mDragState = std::make_unique<DragState>(toWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005076 }
5077
Arthur Hungabbb9d82021-09-01 14:52:30 +00005078 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005079 sp<Connection> fromConnection = getConnectionLocked(fromToken);
5080 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005081 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005082 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005083 CancelationOptions
5084 options(CancelationOptions::CANCEL_POINTER_EVENTS,
5085 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005086 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08005087 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005088 }
5089
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005090 if (DEBUG_FOCUS) {
5091 logDispatchStateLocked();
5092 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005093 } // release lock
5094
5095 // Wake up poll loop since it may need to make new input dispatching choices.
5096 mLooper->wake();
5097 return true;
5098}
5099
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005100// Binder call
5101bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
5102 sp<IBinder> fromToken;
5103 { // acquire lock
5104 std::scoped_lock _l(mLock);
5105
Arthur Hungabbb9d82021-09-01 14:52:30 +00005106 auto it = std::find_if(mTouchStatesByDisplay.begin(), mTouchStatesByDisplay.end(),
5107 [](const auto& pair) { return pair.second.windows.size() == 1; });
5108 if (it == mTouchStatesByDisplay.end()) {
5109 ALOGW("Cannot transfer touch state because there is no exact window being touched");
5110 return false;
5111 }
5112 const int32_t displayId = it->first;
5113 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005114 if (toWindowHandle == nullptr) {
5115 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
5116 return false;
5117 }
5118
Arthur Hungabbb9d82021-09-01 14:52:30 +00005119 TouchState& state = it->second;
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005120 const TouchedWindow& touchedWindow = state.windows[0];
5121 fromToken = touchedWindow.windowHandle->getToken();
5122 } // release lock
5123
5124 return transferTouchFocus(fromToken, destChannelToken);
5125}
5126
Michael Wrightd02c5b62014-02-10 15:10:22 -08005127void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005128 if (DEBUG_FOCUS) {
5129 ALOGD("Resetting and dropping all events (%s).", reason);
5130 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005131
5132 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
5133 synthesizeCancelationEventsForAllConnectionsLocked(options);
5134
5135 resetKeyRepeatLocked();
5136 releasePendingEventLocked();
5137 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005138 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005139
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005140 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005141 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005142 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07005143 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005144}
5145
5146void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005147 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005148 dumpDispatchStateLocked(dump);
5149
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005150 std::istringstream stream(dump);
5151 std::string line;
5152
5153 while (std::getline(stream, line, '\n')) {
5154 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005155 }
5156}
5157
Prabir Pradhan99987712020-11-10 18:43:05 -08005158std::string InputDispatcher::dumpPointerCaptureStateLocked() {
5159 std::string dump;
5160
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005161 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5162 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005163
5164 std::string windowName = "None";
5165 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005166 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005167 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5168 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5169 : "token has capture without window";
5170 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005171 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005172
5173 return dump;
5174}
5175
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005176void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005177 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5178 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5179 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005180 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005181
Tiger Huang721e26f2018-07-24 22:26:19 +08005182 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5183 dump += StringPrintf(INDENT "FocusedApplications:\n");
5184 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5185 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005186 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005187 const std::chrono::duration timeout =
5188 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005189 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005190 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005191 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005192 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005193 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005194 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005195 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005196
Vishnu Nairc519ff72021-01-21 08:23:08 -08005197 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005198 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005199
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005200 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005201 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005202 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
5203 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005204 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005205 state.displayId, toString(state.down), toString(state.split),
5206 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005207 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005208 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005209 for (size_t i = 0; i < state.windows.size(); i++) {
5210 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005211 dump += StringPrintf(INDENT4
5212 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
5213 i, touchedWindow.windowHandle->getName().c_str(),
5214 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005215 }
5216 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005217 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005218 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005219 }
5220 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005221 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005222 }
5223
arthurhung6d4bed92021-03-17 11:59:33 +08005224 if (mDragState) {
5225 dump += StringPrintf(INDENT "DragState:\n");
5226 mDragState->dump(dump, INDENT2);
5227 }
5228
Arthur Hungb92218b2018-08-14 12:00:21 +08005229 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005230 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5231 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5232 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5233 const auto& displayInfo = it->second;
5234 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5235 displayInfo.logicalHeight);
5236 displayInfo.transform.dump(dump, "transform", INDENT4);
5237 } else {
5238 dump += INDENT2 "No DisplayInfo found!\n";
5239 }
5240
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005241 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005242 dump += INDENT2 "Windows:\n";
5243 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005244 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5245 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005246
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005247 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005248 "paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005249 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005250 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005251 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005252 "applicationInfo.name=%s, "
5253 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005254 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005255 i, windowInfo->name.c_str(), windowInfo->id,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005256 windowInfo->displayId, toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07005257 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005258 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005259 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01005260 windowInfo->flags.string().c_str(),
Dominik Laskowski75788452021-02-09 18:51:25 -08005261 ftl::enum_string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01005262 windowInfo->frameLeft, windowInfo->frameTop,
5263 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005264 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005265 windowInfo->applicationInfo.name.c_str(),
5266 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005267 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01005268 dump += StringPrintf(", inputFeatures=%s",
5269 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005270 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005271 "ms, trustedOverlay=%s, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005272 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005273 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005274 millis(windowInfo->dispatchingTimeout),
5275 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005276 toString(windowInfo->token != nullptr),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005277 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005278 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005279 }
5280 } else {
5281 dump += INDENT2 "Windows: <none>\n";
5282 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005283 }
5284 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005285 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005286 }
5287
Michael Wright3dd60e22019-03-27 22:06:44 +00005288 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005289 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005290 const std::vector<Monitor>& monitors = it.second;
5291 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
5292 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005293 }
5294 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005295 const std::vector<Monitor>& monitors = it.second;
5296 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
5297 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005298 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005299 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00005300 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005301 }
5302
5303 nsecs_t currentTime = now();
5304
5305 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005306 if (!mRecentQueue.empty()) {
5307 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005308 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005309 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005310 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005311 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005312 }
5313 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005314 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005315 }
5316
5317 // Dump event currently being dispatched.
5318 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005319 dump += INDENT "PendingEvent:\n";
5320 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005321 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005322 dump += StringPrintf(", age=%" PRId64 "ms\n",
5323 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005324 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005325 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005326 }
5327
5328 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005329 if (!mInboundQueue.empty()) {
5330 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005331 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005332 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005333 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005334 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005335 }
5336 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005337 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005338 }
5339
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005340 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005341 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005342 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5343 const KeyReplacement& replacement = pair.first;
5344 int32_t newKeyCode = pair.second;
5345 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005346 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005347 }
5348 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005349 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005350 }
5351
Prabir Pradhancef936d2021-07-21 16:17:52 +00005352 if (!mCommandQueue.empty()) {
5353 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5354 } else {
5355 dump += INDENT "CommandQueue: <empty>\n";
5356 }
5357
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005358 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005359 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005360 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005361 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005362 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005363 connection->inputChannel->getFd().get(),
5364 connection->getInputChannelName().c_str(),
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005365 connection->getWindowName().c_str(),
5366 ftl::enum_string(connection->status).c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005367 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005368
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005369 if (!connection->outboundQueue.empty()) {
5370 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5371 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005372 dump += dumpQueue(connection->outboundQueue, currentTime);
5373
Michael Wrightd02c5b62014-02-10 15:10:22 -08005374 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005375 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005376 }
5377
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005378 if (!connection->waitQueue.empty()) {
5379 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5380 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005381 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005382 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005383 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005384 }
5385 }
5386 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005387 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005388 }
5389
5390 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005391 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5392 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005393 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005394 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005395 }
5396
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005397 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005398 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5399 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5400 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005401 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005402 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005403}
5404
Michael Wright3dd60e22019-03-27 22:06:44 +00005405void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5406 const size_t numMonitors = monitors.size();
5407 for (size_t i = 0; i < numMonitors; i++) {
5408 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005409 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005410 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5411 dump += "\n";
5412 }
5413}
5414
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005415class LooperEventCallback : public LooperCallback {
5416public:
5417 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5418 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5419
5420private:
5421 std::function<int(int events)> mCallback;
5422};
5423
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005424Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005425 if (DEBUG_CHANNEL_CREATION) {
5426 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5427 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005428
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005429 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005430 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005431 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005432
5433 if (result) {
5434 return base::Error(result) << "Failed to open input channel pair with name " << name;
5435 }
5436
Michael Wrightd02c5b62014-02-10 15:10:22 -08005437 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005438 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005439 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005440 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005441 sp<Connection> connection =
5442 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005443
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005444 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5445 ALOGE("Created a new connection, but the token %p is already known", token.get());
5446 }
5447 mConnectionsByToken.emplace(token, connection);
5448
5449 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5450 this, std::placeholders::_1, token);
5451
5452 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005453 } // release lock
5454
5455 // Wake the looper because some connections have changed.
5456 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005457 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005458}
5459
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005460Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5461 bool isGestureMonitor,
5462 const std::string& name,
5463 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005464 std::shared_ptr<InputChannel> serverChannel;
5465 std::unique_ptr<InputChannel> clientChannel;
5466 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5467 if (result) {
5468 return base::Error(result) << "Failed to open input channel pair with name " << name;
5469 }
5470
Michael Wright3dd60e22019-03-27 22:06:44 +00005471 { // acquire lock
5472 std::scoped_lock _l(mLock);
5473
5474 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005475 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5476 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005477 }
5478
Garfield Tan15601662020-09-22 15:32:38 -07005479 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005480 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005481 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005482
5483 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5484 ALOGE("Created a new connection, but the token %p is already known", token.get());
5485 }
5486 mConnectionsByToken.emplace(token, connection);
5487 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5488 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005489
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005490 auto& monitorsByDisplay =
5491 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005492 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005493
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005494 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Siarhei Vishniakouc961c742021-05-19 19:16:59 +00005495 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5496 displayId, toString(isGestureMonitor), pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005497 }
Garfield Tan15601662020-09-22 15:32:38 -07005498
Michael Wright3dd60e22019-03-27 22:06:44 +00005499 // Wake the looper because some connections have changed.
5500 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005501 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005502}
5503
Garfield Tan15601662020-09-22 15:32:38 -07005504status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005505 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005506 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005507
Garfield Tan15601662020-09-22 15:32:38 -07005508 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005509 if (status) {
5510 return status;
5511 }
5512 } // release lock
5513
5514 // Wake the poll loop because removing the connection may have changed the current
5515 // synchronization state.
5516 mLooper->wake();
5517 return OK;
5518}
5519
Garfield Tan15601662020-09-22 15:32:38 -07005520status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5521 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005522 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005523 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005524 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005525 return BAD_VALUE;
5526 }
5527
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005528 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005529
Michael Wrightd02c5b62014-02-10 15:10:22 -08005530 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005531 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005532 }
5533
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005534 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005535
5536 nsecs_t currentTime = now();
5537 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5538
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005539 connection->status = Connection::Status::ZOMBIE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005540 return OK;
5541}
5542
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005543void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5544 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5545 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005546}
5547
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005548void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005549 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005550 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005551 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005552 std::vector<Monitor>& monitors = it->second;
5553 const size_t numMonitors = monitors.size();
5554 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005555 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005556 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5557 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005558 monitors.erase(monitors.begin() + i);
5559 break;
5560 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005561 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005562 if (monitors.empty()) {
5563 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005564 } else {
5565 ++it;
5566 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005567 }
5568}
5569
Michael Wright3dd60e22019-03-27 22:06:44 +00005570status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5571 { // acquire lock
5572 std::scoped_lock _l(mLock);
Michael Wright3dd60e22019-03-27 22:06:44 +00005573
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005574 TouchState* statePtr = nullptr;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005575 std::shared_ptr<InputChannel> requestingChannel;
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005576 int32_t displayId;
5577 int32_t deviceId;
5578 const std::optional<int32_t> foundGestureMonitorDisplayId =
5579 findGestureMonitorDisplayByTokenLocked(token);
5580
5581 // TODO: Optimize this function for pilfering from windows when removing gesture monitors.
5582 if (foundGestureMonitorDisplayId) {
5583 // A gesture monitor has requested to pilfer pointers.
5584 displayId = *foundGestureMonitorDisplayId;
5585 auto stateIt = mTouchStatesByDisplay.find(displayId);
5586 if (stateIt == mTouchStatesByDisplay.end()) {
5587 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5588 return BAD_VALUE;
5589 }
5590 statePtr = &stateIt->second;
5591
5592 for (const auto& monitor : statePtr->gestureMonitors) {
5593 if (monitor.inputChannel->getConnectionToken() == token) {
5594 requestingChannel = monitor.inputChannel;
5595 deviceId = statePtr->deviceId;
5596 }
5597 }
5598 } else {
5599 // Check if a window has requested to pilfer pointers.
5600 for (auto& [curDisplayId, state] : mTouchStatesByDisplay) {
5601 const sp<WindowInfoHandle>& windowHandle = state.getWindow(token);
5602 if (windowHandle != nullptr) {
5603 displayId = curDisplayId;
5604 requestingChannel = getInputChannelLocked(token);
5605 deviceId = state.deviceId;
5606 statePtr = &state;
5607 break;
5608 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005609 }
5610 }
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005611
5612 if (requestingChannel == nullptr) {
5613 ALOGW("Attempted to pilfer pointers from an un-registered channel or invalid token");
5614 return BAD_VALUE;
5615 }
5616 TouchState& state = *statePtr;
5617 if (!state.down) {
5618 ALOGW("Attempted to pilfer points from a channel without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005619 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005620 return BAD_VALUE;
5621 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005622
5623 // Send cancel events to all the input channels we're stealing from.
5624 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005625 "input channel stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005626 options.deviceId = deviceId;
5627 options.displayId = displayId;
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005628 std::string canceledWindows;
Michael Wright3dd60e22019-03-27 22:06:44 +00005629 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005630 std::shared_ptr<InputChannel> channel =
5631 getInputChannelLocked(window.windowHandle->getToken());
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005632 if (channel != nullptr && channel->getConnectionToken() != token) {
Michael Wright3a240c42019-12-10 20:53:41 +00005633 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005634 canceledWindows += canceledWindows.empty() ? "[" : ", ";
5635 canceledWindows += channel->getName();
Michael Wright3a240c42019-12-10 20:53:41 +00005636 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005637 }
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005638 canceledWindows += canceledWindows.empty() ? "[]" : "]";
5639 ALOGI("Channel %s is stealing touch from %s", requestingChannel->getName().c_str(),
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005640 canceledWindows.c_str());
5641
Michael Wright3dd60e22019-03-27 22:06:44 +00005642 // Then clear the current touch state so we stop dispatching to them as well.
Arthur Hungfbfa5722021-11-16 02:45:54 +00005643 state.split = false;
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005644 state.filterWindowsExcept(token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005645 }
5646 return OK;
5647}
5648
Prabir Pradhan99987712020-11-10 18:43:05 -08005649void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5650 { // acquire lock
5651 std::scoped_lock _l(mLock);
5652 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005653 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005654 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5655 windowHandle != nullptr ? windowHandle->getName().c_str()
5656 : "token without window");
5657 }
5658
Vishnu Nairc519ff72021-01-21 08:23:08 -08005659 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005660 if (focusedToken != windowToken) {
5661 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5662 enabled ? "enable" : "disable");
5663 return;
5664 }
5665
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005666 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08005667 ALOGW("Ignoring request to %s Pointer Capture: "
5668 "window has %s requested pointer capture.",
5669 enabled ? "enable" : "disable", enabled ? "already" : "not");
5670 return;
5671 }
5672
Prabir Pradhan99987712020-11-10 18:43:05 -08005673 setPointerCaptureLocked(enabled);
5674 } // release lock
5675
5676 // Wake the thread to process command entries.
5677 mLooper->wake();
5678}
5679
Michael Wright3dd60e22019-03-27 22:06:44 +00005680std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5681 const sp<IBinder>& token) {
5682 for (const auto& it : mGestureMonitorsByDisplay) {
5683 const std::vector<Monitor>& monitors = it.second;
5684 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005685 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005686 return it.first;
5687 }
5688 }
5689 }
5690 return std::nullopt;
5691}
5692
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005693std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5694 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5695 if (gesturePid.has_value()) {
5696 return gesturePid;
5697 }
5698 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5699}
5700
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005701sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005702 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005703 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005704 }
5705
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005706 for (const auto& [token, connection] : mConnectionsByToken) {
5707 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005708 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005709 }
5710 }
Robert Carr4e670e52018-08-15 13:26:12 -07005711
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005712 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005713}
5714
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005715std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5716 sp<Connection> connection = getConnectionLocked(connectionToken);
5717 if (connection == nullptr) {
5718 return "<nullptr>";
5719 }
5720 return connection->getInputChannelName();
5721}
5722
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005723void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005724 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005725 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005726}
5727
Prabir Pradhancef936d2021-07-21 16:17:52 +00005728void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5729 const sp<Connection>& connection, uint32_t seq,
5730 bool handled, nsecs_t consumeTime) {
5731 // Handle post-event policy actions.
5732 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5733 if (dispatchEntryIt == connection->waitQueue.end()) {
5734 return;
5735 }
5736 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5737 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5738 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5739 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5740 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5741 }
5742 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5743 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5744 connection->inputChannel->getConnectionToken(),
5745 dispatchEntry->deliveryTime, consumeTime, finishTime);
5746 }
5747
5748 bool restartEvent;
5749 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5750 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5751 restartEvent =
5752 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5753 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5754 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5755 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5756 handled);
5757 } else {
5758 restartEvent = false;
5759 }
5760
5761 // Dequeue the event and start the next cycle.
5762 // Because the lock might have been released, it is possible that the
5763 // contents of the wait queue to have been drained, so we need to double-check
5764 // a few things.
5765 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5766 if (dispatchEntryIt != connection->waitQueue.end()) {
5767 dispatchEntry = *dispatchEntryIt;
5768 connection->waitQueue.erase(dispatchEntryIt);
5769 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5770 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5771 if (!connection->responsive) {
5772 connection->responsive = isConnectionResponsive(*connection);
5773 if (connection->responsive) {
5774 // The connection was unresponsive, and now it's responsive.
5775 processConnectionResponsiveLocked(*connection);
5776 }
5777 }
5778 traceWaitQueueLength(*connection);
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005779 if (restartEvent && connection->status == Connection::Status::NORMAL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005780 connection->outboundQueue.push_front(dispatchEntry);
5781 traceOutboundQueueLength(*connection);
5782 } else {
5783 releaseDispatchEntry(dispatchEntry);
5784 }
5785 }
5786
5787 // Start the next dispatch cycle for this connection.
5788 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005789}
5790
Prabir Pradhancef936d2021-07-21 16:17:52 +00005791void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5792 const sp<IBinder>& newToken) {
5793 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5794 scoped_unlock unlock(mLock);
5795 mPolicy->notifyFocusChanged(oldToken, newToken);
5796 };
5797 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005798}
5799
Prabir Pradhancef936d2021-07-21 16:17:52 +00005800void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5801 auto command = [this, token, x, y]() REQUIRES(mLock) {
5802 scoped_unlock unlock(mLock);
5803 mPolicy->notifyDropWindow(token, x, y);
5804 };
5805 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005806}
5807
Prabir Pradhancef936d2021-07-21 16:17:52 +00005808void InputDispatcher::sendUntrustedTouchCommandLocked(const std::string& obscuringPackage) {
5809 auto command = [this, obscuringPackage]() REQUIRES(mLock) {
5810 scoped_unlock unlock(mLock);
5811 mPolicy->notifyUntrustedTouch(obscuringPackage);
5812 };
5813 postCommandLocked(std::move(command));
arthurhungf452d0b2021-01-06 00:19:52 +08005814}
5815
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005816void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5817 if (connection == nullptr) {
5818 LOG_ALWAYS_FATAL("Caller must check for nullness");
5819 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005820 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5821 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005822 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005823 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005824 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005825 return;
5826 }
5827 /**
5828 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5829 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5830 * has changed. This could cause newer entries to time out before the already dispatched
5831 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5832 * processes the events linearly. So providing information about the oldest entry seems to be
5833 * most useful.
5834 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005835 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005836 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5837 std::string reason =
5838 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005839 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005840 ns2ms(currentWait),
5841 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005842 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005843 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005844
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005845 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5846
5847 // Stop waking up for events on this connection, it is already unresponsive
5848 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005849}
5850
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005851void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5852 std::string reason =
5853 StringPrintf("%s does not have a focused window", application->getName().c_str());
5854 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005855
Prabir Pradhancef936d2021-07-21 16:17:52 +00005856 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5857 scoped_unlock unlock(mLock);
5858 mPolicy->notifyNoFocusedWindowAnr(application);
5859 };
5860 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005861}
5862
chaviw98318de2021-05-19 16:45:23 -05005863void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005864 const std::string& reason) {
5865 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5866 updateLastAnrStateLocked(windowLabel, reason);
5867}
5868
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005869void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5870 const std::string& reason) {
5871 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005872 updateLastAnrStateLocked(windowLabel, reason);
5873}
5874
5875void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5876 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005877 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005878 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005879 struct tm tm;
5880 localtime_r(&t, &tm);
5881 char timestr[64];
5882 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005883 mLastAnrState.clear();
5884 mLastAnrState += INDENT "ANR:\n";
5885 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005886 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5887 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005888 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005889}
5890
Prabir Pradhancef936d2021-07-21 16:17:52 +00005891void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5892 KeyEntry& entry) {
5893 const KeyEvent event = createKeyEvent(entry);
5894 nsecs_t delay = 0;
5895 { // release lock
5896 scoped_unlock unlock(mLock);
5897 android::base::Timer t;
5898 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5899 entry.policyFlags);
5900 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5901 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5902 std::to_string(t.duration().count()).c_str());
5903 }
5904 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005905
5906 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005907 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005908 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005909 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005910 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005911 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5912 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005913 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005914}
5915
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005916void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005917 auto command = [this, pid, reason = std::move(reason)]() REQUIRES(mLock) {
5918 scoped_unlock unlock(mLock);
5919 mPolicy->notifyMonitorUnresponsive(pid, reason);
5920 };
5921 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005922}
5923
Prabir Pradhancef936d2021-07-21 16:17:52 +00005924void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005925 std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005926 auto command = [this, token, reason = std::move(reason)]() REQUIRES(mLock) {
5927 scoped_unlock unlock(mLock);
5928 mPolicy->notifyWindowUnresponsive(token, reason);
5929 };
5930 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005931}
5932
5933void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005934 auto command = [this, pid]() REQUIRES(mLock) {
5935 scoped_unlock unlock(mLock);
5936 mPolicy->notifyMonitorResponsive(pid);
5937 };
5938 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005939}
5940
Prabir Pradhancef936d2021-07-21 16:17:52 +00005941void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) {
5942 auto command = [this, connectionToken]() REQUIRES(mLock) {
5943 scoped_unlock unlock(mLock);
5944 mPolicy->notifyWindowResponsive(connectionToken);
5945 };
5946 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005947}
5948
5949/**
5950 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5951 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5952 * command entry to the command queue.
5953 */
5954void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5955 std::string reason) {
5956 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5957 if (connection.monitor) {
5958 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5959 reason.c_str());
5960 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5961 if (!pid.has_value()) {
5962 ALOGE("Could not find unresponsive monitor for connection %s",
5963 connection.inputChannel->getName().c_str());
5964 return;
5965 }
5966 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5967 return;
5968 }
5969 // If not a monitor, must be a window
5970 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5971 reason.c_str());
5972 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5973}
5974
5975/**
5976 * Tell the policy that a connection has become responsive so that it can stop ANR.
5977 */
5978void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5979 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5980 if (connection.monitor) {
5981 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5982 if (!pid.has_value()) {
5983 ALOGE("Could not find responsive monitor for connection %s",
5984 connection.inputChannel->getName().c_str());
5985 return;
5986 }
5987 sendMonitorResponsiveCommandLocked(pid.value());
5988 return;
5989 }
5990 // If not a monitor, must be a window
5991 sendWindowResponsiveCommandLocked(connectionToken);
5992}
5993
Prabir Pradhancef936d2021-07-21 16:17:52 +00005994bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005995 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005996 KeyEntry& keyEntry, bool handled) {
5997 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005998 if (!handled) {
5999 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006000 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006001 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006002 return false;
6003 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006004
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006005 // Get the fallback key state.
6006 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006007 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006008 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006009 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006010 connection->inputState.removeFallbackKey(originalKeyCode);
6011 }
6012
6013 if (handled || !dispatchEntry->hasForegroundTarget()) {
6014 // If the application handles the original key for which we previously
6015 // generated a fallback or if the window is not a foreground window,
6016 // then cancel the associated fallback key, if any.
6017 if (fallbackKeyCode != -1) {
6018 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006019 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6020 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
6021 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6022 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
6023 keyEntry.policyFlags);
6024 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006025 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006026 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006027
6028 mLock.unlock();
6029
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006030 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006031 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006032
6033 mLock.lock();
6034
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006035 // Cancel the fallback key.
6036 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006037 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006038 "application handled the original non-fallback key "
6039 "or is no longer a foreground target, "
6040 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08006041 options.keyCode = fallbackKeyCode;
6042 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006043 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006044 connection->inputState.removeFallbackKey(originalKeyCode);
6045 }
6046 } else {
6047 // If the application did not handle a non-fallback key, first check
6048 // that we are in a good state to perform unhandled key event processing
6049 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006050 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006051 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006052 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6053 ALOGD("Unhandled key event: Skipping unhandled key event processing "
6054 "since this is not an initial down. "
6055 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6056 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6057 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006058 return false;
6059 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006060
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006061 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006062 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6063 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
6064 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6065 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6066 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006067 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006068
6069 mLock.unlock();
6070
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006071 bool fallback =
6072 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006073 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006074
6075 mLock.lock();
6076
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08006077 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006078 connection->inputState.removeFallbackKey(originalKeyCode);
6079 return false;
6080 }
6081
6082 // Latch the fallback keycode for this key on an initial down.
6083 // The fallback keycode cannot change at any other point in the lifecycle.
6084 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006085 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006086 fallbackKeyCode = event.getKeyCode();
6087 } else {
6088 fallbackKeyCode = AKEYCODE_UNKNOWN;
6089 }
6090 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
6091 }
6092
6093 ALOG_ASSERT(fallbackKeyCode != -1);
6094
6095 // Cancel the fallback key if the policy decides not to send it anymore.
6096 // We will continue to dispatch the key to the policy but we will no
6097 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006098 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
6099 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006100 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6101 if (fallback) {
6102 ALOGD("Unhandled key event: Policy requested to send key %d"
6103 "as a fallback for %d, but on the DOWN it had requested "
6104 "to send %d instead. Fallback canceled.",
6105 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
6106 } else {
6107 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6108 "but on the DOWN it had requested to send %d. "
6109 "Fallback canceled.",
6110 originalKeyCode, fallbackKeyCode);
6111 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006112 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006113
6114 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
6115 "canceling fallback, policy no longer desires it");
6116 options.keyCode = fallbackKeyCode;
6117 synthesizeCancelationEventsForConnectionLocked(connection, options);
6118
6119 fallback = false;
6120 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006121 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006122 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006123 }
6124 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006125
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006126 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6127 {
6128 std::string msg;
6129 const KeyedVector<int32_t, int32_t>& fallbackKeys =
6130 connection->inputState.getFallbackKeys();
6131 for (size_t i = 0; i < fallbackKeys.size(); i++) {
6132 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
6133 }
6134 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6135 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006136 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006137 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006138
6139 if (fallback) {
6140 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006141 keyEntry.eventTime = event.getEventTime();
6142 keyEntry.deviceId = event.getDeviceId();
6143 keyEntry.source = event.getSource();
6144 keyEntry.displayId = event.getDisplayId();
6145 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
6146 keyEntry.keyCode = fallbackKeyCode;
6147 keyEntry.scanCode = event.getScanCode();
6148 keyEntry.metaState = event.getMetaState();
6149 keyEntry.repeatCount = event.getRepeatCount();
6150 keyEntry.downTime = event.getDownTime();
6151 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006152
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006153 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6154 ALOGD("Unhandled key event: Dispatching fallback key. "
6155 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
6156 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
6157 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006158 return true; // restart the event
6159 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006160 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6161 ALOGD("Unhandled key event: No fallback key.");
6162 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006163
6164 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006165 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006166 }
6167 }
6168 return false;
6169}
6170
Prabir Pradhancef936d2021-07-21 16:17:52 +00006171bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006172 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006173 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006174 return false;
6175}
6176
Michael Wrightd02c5b62014-02-10 15:10:22 -08006177void InputDispatcher::traceInboundQueueLengthLocked() {
6178 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006179 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006180 }
6181}
6182
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006183void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006184 if (ATRACE_ENABLED()) {
6185 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006186 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6187 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006188 }
6189}
6190
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006191void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006192 if (ATRACE_ENABLED()) {
6193 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006194 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6195 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006196 }
6197}
6198
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006199void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006200 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006201
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006202 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006203 dumpDispatchStateLocked(dump);
6204
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006205 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006206 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006207 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006208 }
6209}
6210
6211void InputDispatcher::monitor() {
6212 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006213 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006214 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006215 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006216}
6217
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006218/**
6219 * Wake up the dispatcher and wait until it processes all events and commands.
6220 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6221 * this method can be safely called from any thread, as long as you've ensured that
6222 * the work you are interested in completing has already been queued.
6223 */
6224bool InputDispatcher::waitForIdle() {
6225 /**
6226 * Timeout should represent the longest possible time that a device might spend processing
6227 * events and commands.
6228 */
6229 constexpr std::chrono::duration TIMEOUT = 100ms;
6230 std::unique_lock lock(mLock);
6231 mLooper->wake();
6232 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6233 return result == std::cv_status::no_timeout;
6234}
6235
Vishnu Naire798b472020-07-23 13:52:21 -07006236/**
6237 * Sets focus to the window identified by the token. This must be called
6238 * after updating any input window handles.
6239 *
6240 * Params:
6241 * request.token - input channel token used to identify the window that should gain focus.
6242 * request.focusedToken - the token that the caller expects currently to be focused. If the
6243 * specified token does not match the currently focused window, this request will be dropped.
6244 * If the specified focused token matches the currently focused window, the call will succeed.
6245 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6246 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6247 * when requesting the focus change. This determines which request gets
6248 * precedence if there is a focus change request from another source such as pointer down.
6249 */
Vishnu Nair958da932020-08-21 17:12:37 -07006250void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6251 { // acquire lock
6252 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006253 std::optional<FocusResolver::FocusChanges> changes =
6254 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6255 if (changes) {
6256 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006257 }
6258 } // release lock
6259 // Wake up poll loop since it may need to make new input dispatching choices.
6260 mLooper->wake();
6261}
6262
Vishnu Nairc519ff72021-01-21 08:23:08 -08006263void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6264 if (changes.oldFocus) {
6265 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006266 if (focusedInputChannel) {
6267 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6268 "focus left window");
6269 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006270 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006271 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006272 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006273 if (changes.newFocus) {
6274 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006275 }
6276
Prabir Pradhan99987712020-11-10 18:43:05 -08006277 // If a window has pointer capture, then it must have focus. We need to ensure that this
6278 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6279 // If the window loses focus before it loses pointer capture, then the window can be in a state
6280 // where it has pointer capture but not focus, violating the contract. Therefore we must
6281 // dispatch the pointer capture event before the focus event. Since focus events are added to
6282 // the front of the queue (above), we add the pointer capture event to the front of the queue
6283 // after the focus events are added. This ensures the pointer capture event ends up at the
6284 // front.
6285 disablePointerCaptureForcedLocked();
6286
Vishnu Nairc519ff72021-01-21 08:23:08 -08006287 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006288 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006289 }
6290}
Vishnu Nair958da932020-08-21 17:12:37 -07006291
Prabir Pradhan99987712020-11-10 18:43:05 -08006292void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006293 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006294 return;
6295 }
6296
6297 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6298
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006299 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006300 setPointerCaptureLocked(false);
6301 }
6302
6303 if (!mWindowTokenWithPointerCapture) {
6304 // No need to send capture changes because no window has capture.
6305 return;
6306 }
6307
6308 if (mPendingEvent != nullptr) {
6309 // Move the pending event to the front of the queue. This will give the chance
6310 // for the pending event to be dropped if it is a captured event.
6311 mInboundQueue.push_front(mPendingEvent);
6312 mPendingEvent = nullptr;
6313 }
6314
6315 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006316 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006317 mInboundQueue.push_front(std::move(entry));
6318}
6319
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006320void InputDispatcher::setPointerCaptureLocked(bool enable) {
6321 mCurrentPointerCaptureRequest.enable = enable;
6322 mCurrentPointerCaptureRequest.seq++;
6323 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006324 scoped_unlock unlock(mLock);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006325 mPolicy->setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006326 };
6327 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006328}
6329
Vishnu Nair599f1412021-06-21 10:39:58 -07006330void InputDispatcher::displayRemoved(int32_t displayId) {
6331 { // acquire lock
6332 std::scoped_lock _l(mLock);
6333 // Set an empty list to remove all handles from the specific display.
6334 setInputWindowsLocked(/* window handles */ {}, displayId);
6335 setFocusedApplicationLocked(displayId, nullptr);
6336 // Call focus resolver to clean up stale requests. This must be called after input windows
6337 // have been removed for the removed display.
6338 mFocusResolver.displayRemoved(displayId);
6339 } // release lock
6340
6341 // Wake up poll loop since it may need to make new input dispatching choices.
6342 mLooper->wake();
6343}
6344
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006345void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
6346 const std::vector<DisplayInfo>& displayInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006347 // The listener sends the windows as a flattened array. Separate the windows by display for
6348 // more convenient parsing.
6349 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
chaviw15fab6f2021-06-07 14:15:52 -05006350 for (const auto& info : windowInfos) {
6351 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
6352 handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
6353 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006354
6355 { // acquire lock
6356 std::scoped_lock _l(mLock);
6357 mDisplayInfos.clear();
6358 for (const auto& displayInfo : displayInfos) {
6359 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6360 }
6361
6362 for (const auto& [displayId, handles] : handlesPerDisplay) {
6363 setInputWindowsLocked(handles, displayId);
6364 }
6365 }
6366 // Wake up poll loop since it may need to make new input dispatching choices.
6367 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006368}
6369
Vishnu Nair062a8672021-09-03 16:07:44 -07006370bool InputDispatcher::shouldDropInput(
6371 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
6372 if (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT) ||
6373 (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT_IF_OBSCURED) &&
6374 isWindowObscuredLocked(windowHandle))) {
6375 ALOGW("Dropping %s event targeting %s as requested by input feature %s on display "
6376 "%" PRId32 ".",
6377 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
6378 windowHandle->getInfo()->inputFeatures.string().c_str(),
6379 windowHandle->getInfo()->displayId);
6380 return true;
6381 }
6382 return false;
6383}
6384
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006385void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
6386 const std::vector<gui::WindowInfo>& windowInfos,
6387 const std::vector<DisplayInfo>& displayInfos) {
6388 mDispatcher.onWindowInfosChanged(windowInfos, displayInfos);
6389}
6390
Arthur Hungdfd528e2021-12-08 13:23:04 +00006391void InputDispatcher::cancelCurrentTouch() {
6392 {
6393 std::scoped_lock _l(mLock);
6394 ALOGD("Canceling all ongoing pointer gestures on all displays.");
6395 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
6396 "cancel current touch");
6397 synthesizeCancelationEventsForAllConnectionsLocked(options);
6398
6399 mTouchStatesByDisplay.clear();
6400 mLastHoverWindowHandle.clear();
6401 }
6402 // Wake up poll loop since there might be work to do.
6403 mLooper->wake();
6404}
6405
Garfield Tane84e6f92019-08-29 17:28:41 -07006406} // namespace android::inputdispatcher