blob: 4f6c696528c7e7a1c1b11fbd091fb0ce137a7f3e [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>
Dominik Laskowski75788452021-02-09 18:51:25 -080027#include <ftl/enum.h>
chaviw15fab6f2021-06-07 14:15:52 -050028#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080029#include <input/InputDevice.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070030#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000031#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070032#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010033#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070034#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080035
Michael Wright44753b12020-07-08 13:48:11 +010036#include <cerrno>
37#include <cinttypes>
38#include <climits>
39#include <cstddef>
40#include <ctime>
41#include <queue>
42#include <sstream>
43
44#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070045#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010046
Michael Wrightd02c5b62014-02-10 15:10:22 -080047#define INDENT " "
48#define INDENT2 " "
49#define INDENT3 " "
50#define INDENT4 " "
51
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080052using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000053using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080054using android::base::StringPrintf;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -070055using android::gui::DisplayInfo;
chaviw98318de2021-05-19 16:45:23 -050056using android::gui::FocusRequest;
57using android::gui::TouchOcclusionMode;
58using android::gui::WindowInfo;
59using android::gui::WindowInfoHandle;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100060using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080061using android::os::InputEventInjectionResult;
62using android::os::InputEventInjectionSync;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080063
Garfield Tane84e6f92019-08-29 17:28:41 -070064namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080065
Prabir Pradhancef936d2021-07-21 16:17:52 +000066namespace {
67
Siarhei Vishniakou63138b62022-03-03 11:33:19 -080068/**
69 * Log detailed debug messages about each inbound event notification to the dispatcher.
70 * Enable this via "adb shell setprop log.tag.InputDispatcherInboundEvent DEBUG" (requires restart)
71 */
72const bool DEBUG_INBOUND_EVENT_DETAILS =
73 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "InboundEvent", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +000074
Siarhei Vishniakou63138b62022-03-03 11:33:19 -080075/**
76 * Log detailed debug messages about each outbound event processed by the dispatcher.
77 * Enable this via "adb shell setprop log.tag.InputDispatcherOutboundEvent DEBUG" (requires restart)
78 */
79const bool DEBUG_OUTBOUND_EVENT_DETAILS =
80 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "OutboundEvent", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +000081
Siarhei Vishniakou63138b62022-03-03 11:33:19 -080082/**
83 * Log debug messages about the dispatch cycle.
84 * Enable this via "adb shell setprop log.tag.InputDispatcherDispatchCycle DEBUG" (requires restart)
85 */
86const bool DEBUG_DISPATCH_CYCLE =
87 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "DispatchCycle", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +000088
Siarhei Vishniakou63138b62022-03-03 11:33:19 -080089/**
90 * Log debug messages about channel creation
91 * Enable this via "adb shell setprop log.tag.InputDispatcherChannelCreation DEBUG" (requires
92 * restart)
93 */
94const bool DEBUG_CHANNEL_CREATION =
95 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "ChannelCreation", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +000096
Siarhei Vishniakou63138b62022-03-03 11:33:19 -080097/**
98 * Log debug messages about input event injection.
99 * Enable this via "adb shell setprop log.tag.InputDispatcherInjection DEBUG" (requires restart)
100 */
101const bool DEBUG_INJECTION =
102 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Injection", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000103
Siarhei Vishniakou63138b62022-03-03 11:33:19 -0800104/**
105 * Log debug messages about input focus tracking.
106 * Enable this via "adb shell setprop log.tag.InputDispatcherFocus DEBUG" (requires restart)
107 */
108const bool DEBUG_FOCUS =
109 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Focus", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000110
Siarhei Vishniakou63138b62022-03-03 11:33:19 -0800111/**
112 * Log debug messages about touch mode event
113 * Enable this via "adb shell setprop log.tag.InputDispatcherTouchMode DEBUG" (requires restart)
114 */
115const bool DEBUG_TOUCH_MODE =
116 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "TouchMode", ANDROID_LOG_INFO);
Antonio Kantekf16f2832021-09-28 04:39:20 +0000117
Siarhei Vishniakou63138b62022-03-03 11:33:19 -0800118/**
119 * Log debug messages about touch occlusion
120 * Enable this via "adb shell setprop log.tag.InputDispatcherTouchOcclusion DEBUG" (requires
121 * restart)
122 */
123const bool DEBUG_TOUCH_OCCLUSION =
124 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "TouchOcclusion", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000125
Siarhei Vishniakou63138b62022-03-03 11:33:19 -0800126/**
127 * Log debug messages about the app switch latency optimization.
128 * Enable this via "adb shell setprop log.tag.InputDispatcherAppSwitch DEBUG" (requires restart)
129 */
130const bool DEBUG_APP_SWITCH =
131 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "AppSwitch", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000132
Siarhei Vishniakou63138b62022-03-03 11:33:19 -0800133/**
134 * Log debug messages about hover events.
135 * Enable this via "adb shell setprop log.tag.InputDispatcherHover DEBUG" (requires restart)
136 */
137const bool DEBUG_HOVER =
138 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Hover", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000139
Prabir Pradhancef936d2021-07-21 16:17:52 +0000140// Temporarily releases a held mutex for the lifetime of the instance.
141// Named to match std::scoped_lock
142class scoped_unlock {
143public:
144 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
145 ~scoped_unlock() { mMutex.lock(); }
146
147private:
148 std::mutex& mMutex;
149};
150
Michael Wrightd02c5b62014-02-10 15:10:22 -0800151// Default input dispatching timeout if there is no focused application or paused window
152// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -0800153const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
154 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
155 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800156
157// Amount of time to allow for all pending events to be processed when an app switch
158// key is on the way. This is used to preempt input dispatch and drop input events
159// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000160constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800161
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800162const std::chrono::duration STALE_EVENT_TIMEOUT = std::chrono::seconds(10) * HwTimeoutMultiplier();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800163
Michael Wrightd02c5b62014-02-10 15:10:22 -0800164// 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 +0000165constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
166
167// Log a warning when an interception call takes longer than this to process.
168constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800169
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700170// Additional key latency in case a connection is still processing some motion events.
171// This will help with the case when a user touched a button that opens a new window,
172// and gives us the chance to dispatch the key to this new window.
173constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
174
Michael Wrightd02c5b62014-02-10 15:10:22 -0800175// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000176constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
177
Antonio Kantekea47acb2021-12-23 12:41:25 -0800178// Event log tags. See EventLogTags.logtags for reference.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000179constexpr int LOGTAG_INPUT_INTERACTION = 62000;
180constexpr int LOGTAG_INPUT_FOCUS = 62001;
Arthur Hungb3307ee2021-10-14 10:57:37 +0000181constexpr int LOGTAG_INPUT_CANCEL = 62003;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000182
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000183inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800184 return systemTime(SYSTEM_TIME_MONOTONIC);
185}
186
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000187inline const char* toString(bool value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800188 return value ? "true" : "false";
189}
190
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000191inline const std::string toString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000192 if (binder == nullptr) {
193 return "<null>";
194 }
195 return StringPrintf("%p", binder.get());
196}
197
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000198inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700199 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
200 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800201}
202
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000203bool isValidKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700205 case AKEY_EVENT_ACTION_DOWN:
206 case AKEY_EVENT_ACTION_UP:
207 return true;
208 default:
209 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800210 }
211}
212
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000213bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700214 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800215 ALOGE("Key event has invalid action code 0x%x", action);
216 return false;
217 }
218 return true;
219}
220
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000221bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800222 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700223 case AMOTION_EVENT_ACTION_DOWN:
224 case AMOTION_EVENT_ACTION_UP:
225 case AMOTION_EVENT_ACTION_CANCEL:
226 case AMOTION_EVENT_ACTION_MOVE:
227 case AMOTION_EVENT_ACTION_OUTSIDE:
228 case AMOTION_EVENT_ACTION_HOVER_ENTER:
229 case AMOTION_EVENT_ACTION_HOVER_MOVE:
230 case AMOTION_EVENT_ACTION_HOVER_EXIT:
231 case AMOTION_EVENT_ACTION_SCROLL:
232 return true;
233 case AMOTION_EVENT_ACTION_POINTER_DOWN:
234 case AMOTION_EVENT_ACTION_POINTER_UP: {
235 int32_t index = getMotionEventActionPointerIndex(action);
236 return index >= 0 && index < pointerCount;
237 }
238 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
239 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
240 return actionButton != 0;
241 default:
242 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800243 }
244}
245
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000246int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500247 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
248}
249
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000250bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
251 const PointerProperties* pointerProperties) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700252 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800253 ALOGE("Motion event has invalid action code 0x%x", action);
254 return false;
255 }
256 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Siarhei Vishniakou01747382022-01-20 13:23:27 -0800257 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %zu.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700258 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800259 return false;
260 }
261 BitSet32 pointerIdBits;
262 for (size_t i = 0; i < pointerCount; i++) {
263 int32_t id = pointerProperties[i].id;
264 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700265 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
266 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800267 return false;
268 }
269 if (pointerIdBits.hasBit(id)) {
270 ALOGE("Motion event has duplicate pointer id %d", id);
271 return false;
272 }
273 pointerIdBits.markBit(id);
274 }
275 return true;
276}
277
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000278std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800279 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000280 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800281 }
282
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000283 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800284 bool first = true;
285 Region::const_iterator cur = region.begin();
286 Region::const_iterator const tail = region.end();
287 while (cur != tail) {
288 if (first) {
289 first = false;
290 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800291 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800292 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800293 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800294 cur++;
295 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000296 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800297}
298
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000299std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500300 constexpr size_t maxEntries = 50; // max events to print
301 constexpr size_t skipBegin = maxEntries / 2;
302 const size_t skipEnd = queue.size() - maxEntries / 2;
303 // skip from maxEntries / 2 ... size() - maxEntries/2
304 // only print from 0 .. skipBegin and then from skipEnd .. size()
305
306 std::string dump;
307 for (size_t i = 0; i < queue.size(); i++) {
308 const DispatchEntry& entry = *queue[i];
309 if (i >= skipBegin && i < skipEnd) {
310 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
311 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
312 continue;
313 }
314 dump.append(INDENT4);
315 dump += entry.eventEntry->getDescription();
316 dump += StringPrintf(", seq=%" PRIu32
317 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
318 entry.seq, entry.targetFlags, entry.resolvedAction,
319 ns2ms(currentTime - entry.eventEntry->eventTime));
320 if (entry.deliveryTime != 0) {
321 // This entry was delivered, so add information on how long we've been waiting
322 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
323 }
324 dump.append("\n");
325 }
326 return dump;
327}
328
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700329/**
330 * Find the entry in std::unordered_map by key, and return it.
331 * If the entry is not found, return a default constructed entry.
332 *
333 * Useful when the entries are vectors, since an empty vector will be returned
334 * if the entry is not found.
335 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
336 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700337template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000338V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700339 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700340 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800341}
342
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000343bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700344 if (first == second) {
345 return true;
346 }
347
348 if (first == nullptr || second == nullptr) {
349 return false;
350 }
351
352 return first->getToken() == second->getToken();
353}
354
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000355bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000356 if (first == nullptr || second == nullptr) {
357 return false;
358 }
359 return first->applicationInfo.token != nullptr &&
360 first->applicationInfo.token == second->applicationInfo.token;
361}
362
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000363std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
364 std::shared_ptr<EventEntry> eventEntry,
365 int32_t inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700366 if (inputTarget.useDefaultPointerTransform()) {
367 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700368 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700369 inputTarget.displayTransform,
370 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000371 }
372
373 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
374 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
375
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700376 std::vector<PointerCoords> pointerCoords;
377 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000378
379 // Use the first pointer information to normalize all other pointers. This could be any pointer
380 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700381 // uses the transform for the normalized pointer.
382 const ui::Transform& firstPointerTransform =
383 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
384 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000385
386 // Iterate through all pointers in the event to normalize against the first.
387 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
388 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
389 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700390 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000391
392 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700393 // First, apply the current pointer's transform to update the coordinates into
394 // window space.
395 pointerCoords[pointerIndex].transform(currTransform);
396 // Next, apply the inverse transform of the normalized coordinates so the
397 // current coordinates are transformed into the normalized coordinate space.
398 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000399 }
400
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700401 std::unique_ptr<MotionEntry> combinedMotionEntry =
402 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
403 motionEntry.deviceId, motionEntry.source,
404 motionEntry.displayId, motionEntry.policyFlags,
405 motionEntry.action, motionEntry.actionButton,
406 motionEntry.flags, motionEntry.metaState,
407 motionEntry.buttonState, motionEntry.classification,
408 motionEntry.edgeFlags, motionEntry.xPrecision,
409 motionEntry.yPrecision, motionEntry.xCursorPosition,
410 motionEntry.yCursorPosition, motionEntry.downTime,
411 motionEntry.pointerCount, motionEntry.pointerProperties,
Prabir Pradhan5beda762021-12-10 09:30:08 +0000412 pointerCoords.data());
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000413
414 if (motionEntry.injectionState) {
415 combinedMotionEntry->injectionState = motionEntry.injectionState;
416 combinedMotionEntry->injectionState->refCount += 1;
417 }
418
419 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700420 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700421 firstPointerTransform, inputTarget.displayTransform,
422 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000423 return dispatchEntry;
424}
425
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000426status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
427 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700428 std::unique_ptr<InputChannel> uniqueServerChannel;
429 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
430
431 serverChannel = std::move(uniqueServerChannel);
432 return result;
433}
434
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500435template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000436bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500437 if (lhs == nullptr && rhs == nullptr) {
438 return true;
439 }
440 if (lhs == nullptr || rhs == nullptr) {
441 return false;
442 }
443 return *lhs == *rhs;
444}
445
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000446KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000447 KeyEvent event;
448 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
449 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
450 entry.repeatCount, entry.downTime, entry.eventTime);
451 return event;
452}
453
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000454bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000455 // Do not keep track of gesture monitors. They receive every event and would disproportionately
456 // affect the statistics.
457 if (connection.monitor) {
458 return false;
459 }
460 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
461 if (!connection.responsive) {
462 return false;
463 }
464 return true;
465}
466
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000467bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000468 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
469 const int32_t& inputEventId = eventEntry.id;
470 if (inputEventId != dispatchEntry.resolvedEventId) {
471 // Event was transmuted
472 return false;
473 }
474 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
475 return false;
476 }
477 // Only track latency for events that originated from hardware
478 if (eventEntry.isSynthesized()) {
479 return false;
480 }
481 const EventEntry::Type& inputEventEntryType = eventEntry.type;
482 if (inputEventEntryType == EventEntry::Type::KEY) {
483 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
484 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
485 return false;
486 }
487 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
488 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
489 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
490 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
491 return false;
492 }
493 } else {
494 // Not a key or a motion
495 return false;
496 }
497 if (!shouldReportMetricsForConnection(connection)) {
498 return false;
499 }
500 return true;
501}
502
Prabir Pradhancef936d2021-07-21 16:17:52 +0000503/**
504 * Connection is responsive if it has no events in the waitQueue that are older than the
505 * current time.
506 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000507bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000508 const nsecs_t currentTime = now();
509 for (const DispatchEntry* entry : connection.waitQueue) {
510 if (entry->timeoutTime < currentTime) {
511 return false;
512 }
513 }
514 return true;
515}
516
Antonio Kantekf16f2832021-09-28 04:39:20 +0000517// Returns true if the event type passed as argument represents a user activity.
518bool isUserActivityEvent(const EventEntry& eventEntry) {
519 switch (eventEntry.type) {
520 case EventEntry::Type::FOCUS:
521 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
522 case EventEntry::Type::DRAG:
523 case EventEntry::Type::TOUCH_MODE_CHANGED:
524 case EventEntry::Type::SENSOR:
525 case EventEntry::Type::CONFIGURATION_CHANGED:
526 return false;
527 case EventEntry::Type::DEVICE_RESET:
528 case EventEntry::Type::KEY:
529 case EventEntry::Type::MOTION:
530 return true;
531 }
532}
533
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800534// Returns true if the given window can accept pointer events at the given display location.
Prabir Pradhand65552b2021-10-07 11:23:50 -0700535bool windowAcceptsTouchAt(const WindowInfo& windowInfo, int32_t displayId, int32_t x, int32_t y,
536 bool isStylus) {
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800537 const auto inputConfig = windowInfo.inputConfig;
538 if (windowInfo.displayId != displayId ||
539 inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800540 return false;
541 }
Prabir Pradhand65552b2021-10-07 11:23:50 -0700542 const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800543 if (inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800544 return false;
545 }
Prabir Pradhan06349042022-02-04 09:19:17 -0800546 if (!windowInfo.touchableRegionContainsPoint(x, y)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800547 return false;
548 }
549 return true;
550}
551
Prabir Pradhand65552b2021-10-07 11:23:50 -0700552bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
553 return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
554 (entry.pointerProperties[pointerIndex].toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS ||
555 entry.pointerProperties[pointerIndex].toolType == AMOTION_EVENT_TOOL_TYPE_ERASER);
556}
557
Prabir Pradhan6dfbf262022-03-14 15:24:30 +0000558// Determines if the given window can be targeted as InputTarget::FLAG_FOREGROUND.
559// Foreground events are only sent to "foreground targetable" windows, but not all gestures sent to
560// such window are necessarily targeted with the flag. For example, an event with ACTION_OUTSIDE can
561// be sent to such a window, but it is not a foreground event and doesn't use
562// InputTarget::FLAG_FOREGROUND.
563bool canReceiveForegroundTouches(const WindowInfo& info) {
564 // A non-touchable window can still receive touch events (e.g. in the case of
565 // STYLUS_INTERCEPTOR), so prevent such windows from receiving foreground events for touches.
566 return !info.inputConfig.test(gui::WindowInfo::InputConfig::NOT_TOUCHABLE) && !info.isSpy();
567}
568
Antonio Kantek48710e42022-03-24 14:19:30 -0700569bool isWindowOwnedBy(const sp<WindowInfoHandle>& windowHandle, int32_t pid, int32_t uid) {
570 if (windowHandle == nullptr) {
571 return false;
572 }
573 const WindowInfo* windowInfo = windowHandle->getInfo();
574 if (pid == windowInfo->ownerPid && uid == windowInfo->ownerUid) {
575 return true;
576 }
577 return false;
578}
579
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000580} // namespace
581
Michael Wrightd02c5b62014-02-10 15:10:22 -0800582// --- InputDispatcher ---
583
Garfield Tan00f511d2019-06-12 16:55:40 -0700584InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800585 : InputDispatcher(policy, STALE_EVENT_TIMEOUT) {}
586
587InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy,
588 std::chrono::nanoseconds staleEventTimeout)
Garfield Tan00f511d2019-06-12 16:55:40 -0700589 : mPolicy(policy),
590 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700591 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800592 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700593 mAppSwitchSawKeyDown(false),
594 mAppSwitchDueTime(LONG_LONG_MAX),
595 mNextUnblockedEvent(nullptr),
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800596 mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
Garfield Tan00f511d2019-06-12 16:55:40 -0700597 mDispatchEnabled(false),
598 mDispatchFrozen(false),
599 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800600 // mInTouchMode will be initialized by the WindowManager to the default device config.
601 // To avoid leaking stack in case that call never comes, and for tests,
602 // initialize it here anyways.
Antonio Kantekf16f2832021-09-28 04:39:20 +0000603 mInTouchMode(kDefaultInTouchMode),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100604 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000605 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800606 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800607 mStaleEventTimeout(staleEventTimeout),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000608 mLatencyAggregator(),
Siarhei Vishniakoubd252722022-01-06 03:49:35 -0800609 mLatencyTracker(&mLatencyAggregator) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800610 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800611 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800612
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700613 mWindowInfoListener = new DispatcherWindowListener(*this);
614 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
615
Yi Kong9b14ac62018-07-17 13:48:38 -0700616 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800617
618 policy->getDispatcherConfiguration(&mConfig);
619}
620
621InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000622 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800623
Prabir Pradhancef936d2021-07-21 16:17:52 +0000624 resetKeyRepeatLocked();
625 releasePendingEventLocked();
626 drainInboundQueueLocked();
627 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800628
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000629 while (!mConnectionsByToken.empty()) {
630 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000631 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
632 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800633 }
634}
635
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700636status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700637 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700638 return ALREADY_EXISTS;
639 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700640 mThread = std::make_unique<InputThread>(
641 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
642 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700643}
644
645status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700646 if (mThread && mThread->isCallingThread()) {
647 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700648 return INVALID_OPERATION;
649 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700650 mThread.reset();
651 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700652}
653
Michael Wrightd02c5b62014-02-10 15:10:22 -0800654void InputDispatcher::dispatchOnce() {
655 nsecs_t nextWakeupTime = LONG_LONG_MAX;
656 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800657 std::scoped_lock _l(mLock);
658 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800659
660 // Run a dispatch loop if there are no pending commands.
661 // The dispatch loop might enqueue commands to run afterwards.
662 if (!haveCommandsLocked()) {
663 dispatchOnceInnerLocked(&nextWakeupTime);
664 }
665
666 // Run all pending commands if there are any.
667 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000668 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800669 nextWakeupTime = LONG_LONG_MIN;
670 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800671
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700672 // If we are still waiting for ack on some events,
673 // we might have to wake up earlier to check if an app is anr'ing.
674 const nsecs_t nextAnrCheck = processAnrsLocked();
675 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
676
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800677 // We are about to enter an infinitely long sleep, because we have no commands or
678 // pending or queued events
679 if (nextWakeupTime == LONG_LONG_MAX) {
680 mDispatcherEnteredIdle.notify_all();
681 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800682 } // release lock
683
684 // Wait for callback or timeout or wake. (make sure we round up, not down)
685 nsecs_t currentTime = now();
686 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
687 mLooper->pollOnce(timeoutMillis);
688}
689
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700690/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500691 * Raise ANR if there is no focused window.
692 * Before the ANR is raised, do a final state check:
693 * 1. The currently focused application must be the same one we are waiting for.
694 * 2. Ensure we still don't have a focused window.
695 */
696void InputDispatcher::processNoFocusedWindowAnrLocked() {
697 // Check if the application that we are waiting for is still focused.
698 std::shared_ptr<InputApplicationHandle> focusedApplication =
699 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
700 if (focusedApplication == nullptr ||
701 focusedApplication->getApplicationToken() !=
702 mAwaitedFocusedApplication->getApplicationToken()) {
703 // Unexpected because we should have reset the ANR timer when focused application changed
704 ALOGE("Waited for a focused window, but focused application has already changed to %s",
705 focusedApplication->getName().c_str());
706 return; // The focused application has changed.
707 }
708
chaviw98318de2021-05-19 16:45:23 -0500709 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500710 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
711 if (focusedWindowHandle != nullptr) {
712 return; // We now have a focused window. No need for ANR.
713 }
714 onAnrLocked(mAwaitedFocusedApplication);
715}
716
717/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700718 * Check if any of the connections' wait queues have events that are too old.
719 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
720 * Return the time at which we should wake up next.
721 */
722nsecs_t InputDispatcher::processAnrsLocked() {
723 const nsecs_t currentTime = now();
724 nsecs_t nextAnrCheck = LONG_LONG_MAX;
725 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
726 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
727 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500728 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700729 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500730 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700731 return LONG_LONG_MIN;
732 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500733 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700734 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
735 }
736 }
737
738 // Check if any connection ANRs are due
739 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
740 if (currentTime < nextAnrCheck) { // most likely scenario
741 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
742 }
743
744 // If we reached here, we have an unresponsive connection.
745 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
746 if (connection == nullptr) {
747 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
748 return nextAnrCheck;
749 }
750 connection->responsive = false;
751 // Stop waking up for this unresponsive connection
752 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000753 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700754 return LONG_LONG_MIN;
755}
756
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800757std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(
758 const sp<Connection>& connection) {
759 if (connection->monitor) {
760 return mMonitorDispatchingTimeout;
761 }
762 const sp<WindowInfoHandle> window =
763 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700764 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500765 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700766 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500767 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700768}
769
Michael Wrightd02c5b62014-02-10 15:10:22 -0800770void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
771 nsecs_t currentTime = now();
772
Jeff Browndc5992e2014-04-11 01:27:26 -0700773 // Reset the key repeat timer whenever normal dispatch is suspended while the
774 // device is in a non-interactive state. This is to ensure that we abort a key
775 // repeat if the device is just coming out of sleep.
776 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800777 resetKeyRepeatLocked();
778 }
779
780 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
781 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100782 if (DEBUG_FOCUS) {
783 ALOGD("Dispatch frozen. Waiting some more.");
784 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800785 return;
786 }
787
788 // Optimize latency of app switches.
789 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
790 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
791 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
792 if (mAppSwitchDueTime < *nextWakeupTime) {
793 *nextWakeupTime = mAppSwitchDueTime;
794 }
795
796 // Ready to start a new event.
797 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700798 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700799 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800800 if (isAppSwitchDue) {
801 // The inbound queue is empty so the app switch key we were waiting
802 // for will never arrive. Stop waiting for it.
803 resetPendingAppSwitchLocked(false);
804 isAppSwitchDue = false;
805 }
806
807 // Synthesize a key repeat if appropriate.
808 if (mKeyRepeatState.lastKeyEntry) {
809 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
810 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
811 } else {
812 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
813 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
814 }
815 }
816 }
817
818 // Nothing to do if there is no pending event.
819 if (!mPendingEvent) {
820 return;
821 }
822 } else {
823 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700824 mPendingEvent = mInboundQueue.front();
825 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800826 traceInboundQueueLengthLocked();
827 }
828
829 // Poke user activity for this event.
830 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700831 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800832 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800833 }
834
835 // Now we have an event to dispatch.
836 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700837 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800838 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700839 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800840 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700841 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800842 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700843 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800844 }
845
846 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700847 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800848 }
849
850 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700851 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700852 const ConfigurationChangedEntry& typedEntry =
853 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700854 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700855 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700856 break;
857 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800858
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700859 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700860 const DeviceResetEntry& typedEntry =
861 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700862 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700863 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700864 break;
865 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800866
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100867 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700868 std::shared_ptr<FocusEntry> typedEntry =
869 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100870 dispatchFocusLocked(currentTime, typedEntry);
871 done = true;
872 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
873 break;
874 }
875
Antonio Kantek7242d8b2021-08-05 16:07:20 -0700876 case EventEntry::Type::TOUCH_MODE_CHANGED: {
877 const auto typedEntry = std::static_pointer_cast<TouchModeEntry>(mPendingEvent);
878 dispatchTouchModeChangeLocked(currentTime, typedEntry);
879 done = true;
880 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
881 break;
882 }
883
Prabir Pradhan99987712020-11-10 18:43:05 -0800884 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
885 const auto typedEntry =
886 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
887 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
888 done = true;
889 break;
890 }
891
arthurhungb89ccb02020-12-30 16:19:01 +0800892 case EventEntry::Type::DRAG: {
893 std::shared_ptr<DragEntry> typedEntry =
894 std::static_pointer_cast<DragEntry>(mPendingEvent);
895 dispatchDragLocked(currentTime, typedEntry);
896 done = true;
897 break;
898 }
899
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700900 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700901 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700902 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700903 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700904 resetPendingAppSwitchLocked(true);
905 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700906 } else if (dropReason == DropReason::NOT_DROPPED) {
907 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700908 }
909 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700910 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700911 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700912 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700913 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
914 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700915 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700916 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700917 break;
918 }
919
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700920 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700921 std::shared_ptr<MotionEntry> motionEntry =
922 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700923 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
924 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800925 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700926 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700927 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700928 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700929 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
930 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700931 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700932 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700933 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800934 }
Chris Yef59a2f42020-10-16 12:55:26 -0700935
936 case EventEntry::Type::SENSOR: {
937 std::shared_ptr<SensorEntry> sensorEntry =
938 std::static_pointer_cast<SensorEntry>(mPendingEvent);
939 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
940 dropReason = DropReason::APP_SWITCH;
941 }
942 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
943 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
944 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
945 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
946 dropReason = DropReason::STALE;
947 }
948 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
949 done = true;
950 break;
951 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800952 }
953
954 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700955 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700956 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800957 }
Michael Wright3a981722015-06-10 15:26:13 +0100958 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800959
960 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700961 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800962 }
963}
964
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800965bool InputDispatcher::isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
966 return std::chrono::nanoseconds(currentTime - entry.eventTime) >= mStaleEventTimeout;
967}
968
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700969/**
970 * Return true if the events preceding this incoming motion event should be dropped
971 * Return false otherwise (the default behaviour)
972 */
973bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700974 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -0700975 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700976
977 // Optimize case where the current application is unresponsive and the user
978 // decides to touch a window in a different application.
979 // If the application takes too long to catch up then we drop all events preceding
980 // the touch into the other window.
981 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700982 int32_t displayId = motionEntry.displayId;
983 int32_t x = static_cast<int32_t>(
984 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
985 int32_t y = static_cast<int32_t>(
986 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Prabir Pradhand65552b2021-10-07 11:23:50 -0700987
988 const bool isStylus = isPointerFromStylus(motionEntry, 0 /*pointerIndex*/);
chaviw98318de2021-05-19 16:45:23 -0500989 sp<WindowInfoHandle> touchedWindowHandle =
Prabir Pradhand65552b2021-10-07 11:23:50 -0700990 findTouchedWindowAtLocked(displayId, x, y, nullptr, isStylus);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700991 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700992 touchedWindowHandle->getApplicationToken() !=
993 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700994 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700995 ALOGI("Pruning input queue because user touched a different application while waiting "
996 "for %s",
997 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700998 return true;
999 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001000
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001001 // Alternatively, maybe there's a spy window that could handle this event.
1002 const std::vector<sp<WindowInfoHandle>> touchedSpies =
1003 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
1004 for (const auto& windowHandle : touchedSpies) {
1005 const sp<Connection> connection = getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +00001006 if (connection != nullptr && connection->responsive) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001007 // This spy window could take more input. Drop all events preceding this
1008 // event, so that the spy window can get a chance to receive the stream.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001009 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001010 "responsive spy window that may handle the event.",
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001011 mAwaitedFocusedApplication->getName().c_str());
1012 return true;
1013 }
1014 }
1015 }
1016
1017 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
1018 // yet been processed by some connections, the dispatcher will wait for these motion
1019 // events to be processed before dispatching the key event. This is because these motion events
1020 // may cause a new window to be launched, which the user might expect to receive focus.
1021 // To prevent waiting forever for such events, just send the key to the currently focused window
1022 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
1023 ALOGD("Received a new pointer down event, stop waiting for events to process and "
1024 "just send the pending key event to the focused window.");
1025 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001026 }
1027 return false;
1028}
1029
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001030bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001031 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001032 mInboundQueue.push_back(std::move(newEntry));
1033 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001034 traceInboundQueueLengthLocked();
1035
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001036 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001037 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001038 // Optimize app switch latency.
1039 // If the application takes too long to catch up then we drop all events preceding
1040 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001041 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001042 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001043 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001044 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001045 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001046 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001047 if (DEBUG_APP_SWITCH) {
1048 ALOGD("App switch is pending!");
1049 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001050 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001051 mAppSwitchSawKeyDown = false;
1052 needWake = true;
1053 }
1054 }
1055 }
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001056
1057 // If a new up event comes in, and the pending event with same key code has been asked
1058 // to try again later because of the policy. We have to reset the intercept key wake up
1059 // time for it may have been handled in the policy and could be dropped.
1060 if (keyEntry.action == AKEY_EVENT_ACTION_UP && mPendingEvent &&
1061 mPendingEvent->type == EventEntry::Type::KEY) {
1062 KeyEntry& pendingKey = static_cast<KeyEntry&>(*mPendingEvent);
1063 if (pendingKey.keyCode == keyEntry.keyCode &&
1064 pendingKey.interceptKeyResult ==
1065 KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1066 pendingKey.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1067 pendingKey.interceptKeyWakeupTime = 0;
1068 needWake = true;
1069 }
1070 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001071 break;
1072 }
1073
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001074 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001075 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
1076 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001077 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001078 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001079 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001081 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001082 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1083 break;
1084 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001085 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001086 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001087 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001088 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001089 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1090 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001091 // nothing to do
1092 break;
1093 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001094 }
1095
1096 return needWake;
1097}
1098
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001099void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001100 // Do not store sensor event in recent queue to avoid flooding the queue.
1101 if (entry->type != EventEntry::Type::SENSOR) {
1102 mRecentQueue.push_back(entry);
1103 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001104 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001105 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001106 }
1107}
1108
chaviw98318de2021-05-19 16:45:23 -05001109sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1110 int32_t y, TouchState* touchState,
Prabir Pradhand65552b2021-10-07 11:23:50 -07001111 bool isStylus,
chaviw98318de2021-05-19 16:45:23 -05001112 bool addOutsideTargets,
1113 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001114 if (addOutsideTargets && touchState == nullptr) {
1115 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001116 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001117 // Traverse windows from front to back to find touched window.
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001118 const auto& windowHandles = getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05001119 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001120 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001121 continue;
1122 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001123
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001124 const WindowInfo& info = *windowHandle->getInfo();
Prabir Pradhand65552b2021-10-07 11:23:50 -07001125 if (!info.isSpy() && windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001126 return windowHandle;
1127 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001128
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08001129 if (addOutsideTargets &&
1130 info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001131 touchState->addOrUpdateWindow(windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1132 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001133 }
1134 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001135 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001136}
1137
Prabir Pradhand65552b2021-10-07 11:23:50 -07001138std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
1139 int32_t displayId, int32_t x, int32_t y, bool isStylus) const {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001140 // Traverse windows from front to back and gather the touched spy windows.
1141 std::vector<sp<WindowInfoHandle>> spyWindows;
1142 const auto& windowHandles = getWindowHandlesLocked(displayId);
1143 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1144 const WindowInfo& info = *windowHandle->getInfo();
1145
Prabir Pradhand65552b2021-10-07 11:23:50 -07001146 if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001147 continue;
1148 }
1149 if (!info.isSpy()) {
1150 // The first touched non-spy window was found, so return the spy windows touched so far.
1151 return spyWindows;
1152 }
1153 spyWindows.push_back(windowHandle);
1154 }
1155 return spyWindows;
1156}
1157
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001158void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001159 const char* reason;
1160 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001161 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001162 if (DEBUG_INBOUND_EVENT_DETAILS) {
1163 ALOGD("Dropped event because policy consumed it.");
1164 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001165 reason = "inbound event was dropped because the policy consumed it";
1166 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001167 case DropReason::DISABLED:
1168 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001169 ALOGI("Dropped event because input dispatch is disabled.");
1170 }
1171 reason = "inbound event was dropped because input dispatch is disabled";
1172 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001173 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001174 ALOGI("Dropped event because of pending overdue app switch.");
1175 reason = "inbound event was dropped because of pending overdue app switch";
1176 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001177 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001178 ALOGI("Dropped event because the current application is not responding and the user "
1179 "has started interacting with a different application.");
1180 reason = "inbound event was dropped because the current application is not responding "
1181 "and the user has started interacting with a different application";
1182 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001183 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001184 ALOGI("Dropped event because it is stale.");
1185 reason = "inbound event was dropped because it is stale";
1186 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001187 case DropReason::NO_POINTER_CAPTURE:
1188 ALOGI("Dropped event because there is no window with Pointer Capture.");
1189 reason = "inbound event was dropped because there is no window with Pointer Capture";
1190 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001191 case DropReason::NOT_DROPPED: {
1192 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001193 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001194 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001195 }
1196
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001197 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001198 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001199 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1200 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001201 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001202 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001203 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001204 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1205 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001206 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1207 synthesizeCancelationEventsForAllConnectionsLocked(options);
1208 } else {
1209 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1210 synthesizeCancelationEventsForAllConnectionsLocked(options);
1211 }
1212 break;
1213 }
Chris Yef59a2f42020-10-16 12:55:26 -07001214 case EventEntry::Type::SENSOR: {
1215 break;
1216 }
arthurhungb89ccb02020-12-30 16:19:01 +08001217 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1218 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001219 break;
1220 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001221 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001222 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001223 case EventEntry::Type::CONFIGURATION_CHANGED:
1224 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001225 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001226 break;
1227 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001228 }
1229}
1230
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001231static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001232 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1233 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001234}
1235
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001236bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1237 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1238 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1239 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001240}
1241
1242bool InputDispatcher::isAppSwitchPendingLocked() {
1243 return mAppSwitchDueTime != LONG_LONG_MAX;
1244}
1245
1246void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1247 mAppSwitchDueTime = LONG_LONG_MAX;
1248
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001249 if (DEBUG_APP_SWITCH) {
1250 if (handled) {
1251 ALOGD("App switch has arrived.");
1252 } else {
1253 ALOGD("App switch was abandoned.");
1254 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001255 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001256}
1257
Michael Wrightd02c5b62014-02-10 15:10:22 -08001258bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001259 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001260}
1261
Prabir Pradhancef936d2021-07-21 16:17:52 +00001262bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001263 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001264 return false;
1265 }
1266
1267 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001268 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001269 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001270 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1271 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001272 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001273 return true;
1274}
1275
Prabir Pradhancef936d2021-07-21 16:17:52 +00001276void InputDispatcher::postCommandLocked(Command&& command) {
1277 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001278}
1279
1280void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001281 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001282 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001283 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001284 releaseInboundEventLocked(entry);
1285 }
1286 traceInboundQueueLengthLocked();
1287}
1288
1289void InputDispatcher::releasePendingEventLocked() {
1290 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001291 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001292 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001293 }
1294}
1295
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001296void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001297 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001298 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001299 if (DEBUG_DISPATCH_CYCLE) {
1300 ALOGD("Injected inbound event was dropped.");
1301 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001302 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001303 }
1304 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001305 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001306 }
1307 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001308}
1309
1310void InputDispatcher::resetKeyRepeatLocked() {
1311 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001312 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001313 }
1314}
1315
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001316std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1317 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001318
Michael Wright2e732952014-09-24 13:26:59 -07001319 uint32_t policyFlags = entry->policyFlags &
1320 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001321
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001322 std::shared_ptr<KeyEntry> newEntry =
1323 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1324 entry->source, entry->displayId, policyFlags, entry->action,
1325 entry->flags, entry->keyCode, entry->scanCode,
1326 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001327
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001328 newEntry->syntheticRepeat = true;
1329 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001330 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001331 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001332}
1333
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001334bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001335 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001336 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1337 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1338 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001339
1340 // Reset key repeating in case a keyboard device was added or removed or something.
1341 resetKeyRepeatLocked();
1342
1343 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001344 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1345 scoped_unlock unlock(mLock);
1346 mPolicy->notifyConfigurationChanged(eventTime);
1347 };
1348 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001349 return true;
1350}
1351
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001352bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1353 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001354 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1355 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1356 entry.deviceId);
1357 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001358
liushenxiang42232912021-05-21 20:24:09 +08001359 // Reset key repeating in case a keyboard device was disabled or enabled.
1360 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1361 resetKeyRepeatLocked();
1362 }
1363
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001364 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001365 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001366 synthesizeCancelationEventsForAllConnectionsLocked(options);
1367 return true;
1368}
1369
Vishnu Nairad321cd2020-08-20 16:40:21 -07001370void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001371 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001372 if (mPendingEvent != nullptr) {
1373 // Move the pending event to the front of the queue. This will give the chance
1374 // for the pending event to get dispatched to the newly focused window
1375 mInboundQueue.push_front(mPendingEvent);
1376 mPendingEvent = nullptr;
1377 }
1378
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001379 std::unique_ptr<FocusEntry> focusEntry =
1380 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1381 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001382
1383 // This event should go to the front of the queue, but behind all other focus events
1384 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001385 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001386 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001387 [](const std::shared_ptr<EventEntry>& event) {
1388 return event->type == EventEntry::Type::FOCUS;
1389 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001390
1391 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001392 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001393}
1394
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001395void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001396 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001397 if (channel == nullptr) {
1398 return; // Window has gone away
1399 }
1400 InputTarget target;
1401 target.inputChannel = channel;
1402 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1403 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001404 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1405 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001406 std::string reason = std::string("reason=").append(entry->reason);
1407 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001408 dispatchEventLocked(currentTime, entry, {target});
1409}
1410
Prabir Pradhan99987712020-11-10 18:43:05 -08001411void InputDispatcher::dispatchPointerCaptureChangedLocked(
1412 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1413 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001414 dropReason = DropReason::NOT_DROPPED;
1415
Prabir Pradhan99987712020-11-10 18:43:05 -08001416 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001417 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001418
1419 if (entry->pointerCaptureRequest.enable) {
1420 // Enable Pointer Capture.
1421 if (haveWindowWithPointerCapture &&
1422 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1423 LOG_ALWAYS_FATAL("This request to enable Pointer Capture has already been dispatched "
1424 "to the window.");
1425 }
1426 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001427 // This can happen if a window requests capture and immediately releases capture.
1428 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001429 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001430 return;
1431 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001432 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1433 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1434 return;
1435 }
1436
Vishnu Nairc519ff72021-01-21 08:23:08 -08001437 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001438 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1439 mWindowTokenWithPointerCapture = token;
1440 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001441 // Disable Pointer Capture.
1442 // We do not check if the sequence number matches for requests to disable Pointer Capture
1443 // for two reasons:
1444 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1445 // to disable capture with the same sequence number: one generated by
1446 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1447 // Capture being disabled in InputReader.
1448 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1449 // actual Pointer Capture state that affects events being generated by input devices is
1450 // in InputReader.
1451 if (!haveWindowWithPointerCapture) {
1452 // Pointer capture was already forcefully disabled because of focus change.
1453 dropReason = DropReason::NOT_DROPPED;
1454 return;
1455 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001456 token = mWindowTokenWithPointerCapture;
1457 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001458 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001459 setPointerCaptureLocked(false);
1460 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001461 }
1462
1463 auto channel = getInputChannelLocked(token);
1464 if (channel == nullptr) {
1465 // Window has gone away, clean up Pointer Capture state.
1466 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001467 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001468 setPointerCaptureLocked(false);
1469 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001470 return;
1471 }
1472 InputTarget target;
1473 target.inputChannel = channel;
1474 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1475 entry->dispatchInProgress = true;
1476 dispatchEventLocked(currentTime, entry, {target});
1477
1478 dropReason = DropReason::NOT_DROPPED;
1479}
1480
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001481void InputDispatcher::dispatchTouchModeChangeLocked(nsecs_t currentTime,
1482 const std::shared_ptr<TouchModeEntry>& entry) {
1483 const std::vector<sp<WindowInfoHandle>>& windowHandles =
1484 getWindowHandlesLocked(mFocusedDisplayId);
1485 if (windowHandles.empty()) {
1486 return;
1487 }
1488 const std::vector<InputTarget> inputTargets =
1489 getInputTargetsFromWindowHandlesLocked(windowHandles);
1490 if (inputTargets.empty()) {
1491 return;
1492 }
1493 entry->dispatchInProgress = true;
1494 dispatchEventLocked(currentTime, entry, inputTargets);
1495}
1496
1497std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1498 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1499 std::vector<InputTarget> inputTargets;
1500 for (const sp<WindowInfoHandle>& handle : windowHandles) {
1501 // TODO(b/193718270): Due to performance concerns, consider notifying visible windows only.
1502 const sp<IBinder>& token = handle->getToken();
1503 if (token == nullptr) {
1504 continue;
1505 }
1506 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1507 if (channel == nullptr) {
1508 continue; // Window has gone away
1509 }
1510 InputTarget target;
1511 target.inputChannel = channel;
1512 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1513 inputTargets.push_back(target);
1514 }
1515 return inputTargets;
1516}
1517
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001518bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001519 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001520 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001521 if (!entry->dispatchInProgress) {
1522 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1523 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1524 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1525 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001526 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001527 // We have seen two identical key downs in a row which indicates that the device
1528 // driver is automatically generating key repeats itself. We take note of the
1529 // repeat here, but we disable our own next key repeat timer since it is clear that
1530 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001531 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1532 // Make sure we don't get key down from a different device. If a different
1533 // device Id has same key pressed down, the new device Id will replace the
1534 // current one to hold the key repeat with repeat count reset.
1535 // In the future when got a KEY_UP on the device id, drop it and do not
1536 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001537 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1538 resetKeyRepeatLocked();
1539 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1540 } else {
1541 // Not a repeat. Save key down state in case we do see a repeat later.
1542 resetKeyRepeatLocked();
1543 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1544 }
1545 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001546 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1547 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001548 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001549 if (DEBUG_INBOUND_EVENT_DETAILS) {
1550 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1551 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001552 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001553 resetKeyRepeatLocked();
1554 }
1555
1556 if (entry->repeatCount == 1) {
1557 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1558 } else {
1559 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1560 }
1561
1562 entry->dispatchInProgress = true;
1563
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001564 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001565 }
1566
1567 // Handle case where the policy asked us to try again later last time.
1568 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1569 if (currentTime < entry->interceptKeyWakeupTime) {
1570 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1571 *nextWakeupTime = entry->interceptKeyWakeupTime;
1572 }
1573 return false; // wait until next wakeup
1574 }
1575 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1576 entry->interceptKeyWakeupTime = 0;
1577 }
1578
1579 // Give the policy a chance to intercept the key.
1580 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1581 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001582 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001583 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001584
1585 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1586 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1587 };
1588 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001589 return false; // wait for the command to run
1590 } else {
1591 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1592 }
1593 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001594 if (*dropReason == DropReason::NOT_DROPPED) {
1595 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001596 }
1597 }
1598
1599 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001600 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001601 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001602 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1603 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001604 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605 return true;
1606 }
1607
1608 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001609 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001610 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001611 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001612 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001613 return false;
1614 }
1615
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001616 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001617 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001618 return true;
1619 }
1620
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001621 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001622 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001623
1624 // Dispatch the key.
1625 dispatchEventLocked(currentTime, entry, inputTargets);
1626 return true;
1627}
1628
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001629void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001630 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1631 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1632 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1633 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1634 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1635 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1636 entry.metaState, entry.repeatCount, entry.downTime);
1637 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001638}
1639
Prabir Pradhancef936d2021-07-21 16:17:52 +00001640void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1641 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001642 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001643 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1644 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1645 "source=0x%x, sensorType=%s",
1646 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001647 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001648 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001649 auto command = [this, entry]() REQUIRES(mLock) {
1650 scoped_unlock unlock(mLock);
1651
1652 if (entry->accuracyChanged) {
1653 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1654 }
1655 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1656 entry->hwTimestamp, entry->values);
1657 };
1658 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001659}
1660
1661bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001662 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1663 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001664 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001665 }
Chris Yef59a2f42020-10-16 12:55:26 -07001666 { // acquire lock
1667 std::scoped_lock _l(mLock);
1668
1669 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1670 std::shared_ptr<EventEntry> entry = *it;
1671 if (entry->type == EventEntry::Type::SENSOR) {
1672 it = mInboundQueue.erase(it);
1673 releaseInboundEventLocked(entry);
1674 }
1675 }
1676 }
1677 return true;
1678}
1679
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001680bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001681 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001682 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001683 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001684 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001685 entry->dispatchInProgress = true;
1686
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001687 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001688 }
1689
1690 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001691 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001692 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001693 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1694 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001695 return true;
1696 }
1697
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001698 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001699
1700 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001701 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001702
1703 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001704 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001705 if (isPointerEvent) {
1706 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001707 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001708 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001709 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001710 } else {
1711 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001712 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001713 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001714 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001715 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001716 return false;
1717 }
1718
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001719 setInjectionResult(*entry, injectionResult);
Prabir Pradhan4df80f52022-04-05 18:33:16 +00001720 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
1721 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001722 return true;
1723 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001724 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001725 CancelationOptions::Mode mode(isPointerEvent
1726 ? CancelationOptions::CANCEL_POINTER_EVENTS
1727 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1728 CancelationOptions options(mode, "input event injection failed");
1729 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001730 return true;
1731 }
1732
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001733 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001734 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001735
1736 // Dispatch the motion.
1737 if (conflictingPointerActions) {
1738 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001739 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001740 synthesizeCancelationEventsForAllConnectionsLocked(options);
1741 }
1742 dispatchEventLocked(currentTime, entry, inputTargets);
1743 return true;
1744}
1745
chaviw98318de2021-05-19 16:45:23 -05001746void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001747 bool isExiting, const MotionEntry& motionEntry) {
1748 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1749 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1750 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1751 PointerCoords pointerCoords;
1752 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1753 pointerCoords.transform(windowHandle->getInfo()->transform);
1754
1755 std::unique_ptr<DragEntry> dragEntry =
1756 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1757 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1758 pointerCoords.getY());
1759
1760 enqueueInboundEventLocked(std::move(dragEntry));
1761}
1762
1763void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1764 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1765 if (channel == nullptr) {
1766 return; // Window has gone away
1767 }
1768 InputTarget target;
1769 target.inputChannel = channel;
1770 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1771 entry->dispatchInProgress = true;
1772 dispatchEventLocked(currentTime, entry, {target});
1773}
1774
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001775void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001776 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1777 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1778 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001779 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001780 "metaState=0x%x, buttonState=0x%x,"
1781 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1782 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001783 entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
1784 entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.edgeFlags,
1785 entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001786
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001787 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1788 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1789 "x=%f, y=%f, pressure=%f, size=%f, "
1790 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1791 "orientation=%f",
1792 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1793 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1794 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1795 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1796 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1797 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1798 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1799 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1800 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1801 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1802 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001803 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001804}
1805
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001806void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1807 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001808 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001809 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001810 if (DEBUG_DISPATCH_CYCLE) {
1811 ALOGD("dispatchEventToCurrentInputTargets");
1812 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001813
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001814 updateInteractionTokensLocked(*eventEntry, inputTargets);
1815
Michael Wrightd02c5b62014-02-10 15:10:22 -08001816 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1817
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001818 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001819
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001820 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001821 sp<Connection> connection =
1822 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001823 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001824 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001825 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001826 if (DEBUG_FOCUS) {
1827 ALOGD("Dropping event delivery to target with channel '%s' because it "
1828 "is no longer registered with the input dispatcher.",
1829 inputTarget.inputChannel->getName().c_str());
1830 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001831 }
1832 }
1833}
1834
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001835void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1836 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1837 // If the policy decides to close the app, we will get a channel removal event via
1838 // unregisterInputChannel, and will clean up the connection that way. We are already not
1839 // sending new pointers to the connection when it blocked, but focused events will continue to
1840 // pile up.
1841 ALOGW("Canceling events for %s because it is unresponsive",
1842 connection->inputChannel->getName().c_str());
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08001843 if (connection->status == Connection::Status::NORMAL) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001844 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1845 "application not responding");
1846 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001847 }
1848}
1849
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001850void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001851 if (DEBUG_FOCUS) {
1852 ALOGD("Resetting ANR timeouts.");
1853 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001854
1855 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001856 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001857 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001858}
1859
Tiger Huang721e26f2018-07-24 22:26:19 +08001860/**
1861 * Get the display id that the given event should go to. If this event specifies a valid display id,
1862 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1863 * Focused display is the display that the user most recently interacted with.
1864 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001865int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001866 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001867 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001868 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001869 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1870 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001871 break;
1872 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001873 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001874 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1875 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001876 break;
1877 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00001878 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001879 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001880 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001881 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001882 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001883 case EventEntry::Type::SENSOR:
1884 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001885 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001886 return ADISPLAY_ID_NONE;
1887 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001888 }
1889 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1890}
1891
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001892bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1893 const char* focusedWindowName) {
1894 if (mAnrTracker.empty()) {
1895 // already processed all events that we waited for
1896 mKeyIsWaitingForEventsTimeout = std::nullopt;
1897 return false;
1898 }
1899
1900 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1901 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001902 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001903 mKeyIsWaitingForEventsTimeout = currentTime +
1904 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1905 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001906 return true;
1907 }
1908
1909 // We still have pending events, and already started the timer
1910 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1911 return true; // Still waiting
1912 }
1913
1914 // Waited too long, and some connection still hasn't processed all motions
1915 // Just send the key to the focused window
1916 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1917 focusedWindowName);
1918 mKeyIsWaitingForEventsTimeout = std::nullopt;
1919 return false;
1920}
1921
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001922InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1923 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1924 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001925 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001926
Tiger Huang721e26f2018-07-24 22:26:19 +08001927 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001928 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001929 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001930 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1931
Michael Wrightd02c5b62014-02-10 15:10:22 -08001932 // If there is no currently focused window and no focused application
1933 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001934 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1935 ALOGI("Dropping %s event because there is no focused window or focused application in "
1936 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08001937 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001938 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001939 }
1940
Vishnu Nair062a8672021-09-03 16:07:44 -07001941 // Drop key events if requested by input feature
1942 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
1943 return InputEventInjectionResult::FAILED;
1944 }
1945
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001946 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1947 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1948 // start interacting with another application via touch (app switch). This code can be removed
1949 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1950 // an app is expected to have a focused window.
1951 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1952 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1953 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001954 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1955 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1956 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001957 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001958 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001959 ALOGW("Waiting because no window has focus but %s may eventually add a "
1960 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001961 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001962 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001963 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001964 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1965 // Already raised ANR. Drop the event
1966 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08001967 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001968 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001969 } else {
1970 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001971 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001972 }
1973 }
1974
1975 // we have a valid, non-null focused window
1976 resetNoFocusedWindowTimeoutLocked();
1977
Prabir Pradhan4df80f52022-04-05 18:33:16 +00001978 // Check permissions.
1979 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
1980 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001981 }
1982
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08001983 if (focusedWindowHandle->getInfo()->inputConfig.test(
1984 WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001985 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001986 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001987 }
1988
1989 // If the event is a key event, then we must wait for all previous events to
1990 // complete before delivering it because previous events may have the
1991 // side-effect of transferring focus to a different window and we want to
1992 // ensure that the following keys are sent to the new window.
1993 //
1994 // Suppose the user touches a button in a window then immediately presses "A".
1995 // If the button causes a pop-up window to appear then we want to ensure that
1996 // the "A" key is delivered to the new pop-up window. This is because users
1997 // often anticipate pending UI changes when typing on a keyboard.
1998 // To obtain this behavior, we must serialize key events with respect to all
1999 // prior input events.
2000 if (entry.type == EventEntry::Type::KEY) {
2001 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
2002 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002003 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002004 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002005 }
2006
2007 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08002008 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002009 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
2010 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002011
2012 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002013 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002014}
2015
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002016/**
2017 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
2018 * that are currently unresponsive.
2019 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002020std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
2021 const std::vector<Monitor>& monitors) const {
2022 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002023 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002024 [this](const Monitor& monitor) REQUIRES(mLock) {
2025 sp<Connection> connection =
2026 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002027 if (connection == nullptr) {
2028 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002029 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002030 return false;
2031 }
2032 if (!connection->responsive) {
2033 ALOGW("Unresponsive monitor %s will not get the new gesture",
2034 connection->inputChannel->getName().c_str());
2035 return false;
2036 }
2037 return true;
2038 });
2039 return responsiveMonitors;
2040}
2041
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002042InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
2043 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
2044 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002045 ATRACE_CALL();
Prabir Pradhan4df80f52022-04-05 18:33:16 +00002046 enum InjectionPermission {
2047 INJECTION_PERMISSION_UNKNOWN,
2048 INJECTION_PERMISSION_GRANTED,
2049 INJECTION_PERMISSION_DENIED
2050 };
Michael Wrightd02c5b62014-02-10 15:10:22 -08002051
Michael Wrightd02c5b62014-02-10 15:10:22 -08002052 // For security reasons, we defer updating the touch state until we are sure that
2053 // event injection will be allowed.
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002054 const int32_t displayId = entry.displayId;
2055 const int32_t action = entry.action;
2056 const int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002057
2058 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002059 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Prabir Pradhan4df80f52022-04-05 18:33:16 +00002060 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05002061 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
2062 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002063
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002064 // Copy current touch state into tempTouchState.
2065 // This state will be used to update mTouchStatesByDisplay at the end of this function.
2066 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07002067 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002068 TouchState tempTouchState;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002069 if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
2070 oldState = &(it->second);
Prabir Pradhane680f9b2022-02-04 04:24:00 -08002071 tempTouchState = *oldState;
Jeff Brownf086ddb2014-02-11 14:28:48 -08002072 }
2073
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002074 bool isSplit = tempTouchState.split;
2075 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
2076 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
2077 tempTouchState.displayId != displayId);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002078
2079 const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2080 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2081 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
2082 const bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2083 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002084 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002085 bool wrongDevice = false;
2086 if (newGesture) {
2087 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002088 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002089 ALOGI("Dropping event because a pointer for a different device is already down "
2090 "in display %" PRId32,
2091 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002092 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002093 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002094 switchedDevice = false;
2095 wrongDevice = true;
2096 goto Failed;
2097 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002098 tempTouchState.reset();
2099 tempTouchState.down = down;
2100 tempTouchState.deviceId = entry.deviceId;
2101 tempTouchState.source = entry.source;
2102 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002103 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002104 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002105 ALOGI("Dropping move event because a pointer for a different device is already active "
2106 "in display %" PRId32,
2107 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002108 // TODO: test multiple simultaneous input streams.
Prabir Pradhan4df80f52022-04-05 18:33:16 +00002109 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002110 switchedDevice = false;
2111 wrongDevice = true;
2112 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002113 }
2114
2115 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2116 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2117
Garfield Tan00f511d2019-06-12 16:55:40 -07002118 int32_t x;
2119 int32_t y;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002120 const int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07002121 // Always dispatch mouse events to cursor position.
2122 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002123 x = int32_t(entry.xCursorPosition);
2124 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07002125 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002126 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
2127 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07002128 }
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002129 const bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Prabir Pradhand65552b2021-10-07 11:23:50 -07002130 const bool isStylus = isPointerFromStylus(entry, pointerIndex);
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002131 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
Prabir Pradhand65552b2021-10-07 11:23:50 -07002132 isStylus, isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00002133
Michael Wrightd02c5b62014-02-10 15:10:22 -08002134 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002135 if (newTouchedWindowHandle == nullptr) {
Arthur Hungb3307ee2021-10-14 10:57:37 +00002136 ALOGD("No new touched window at (%" PRId32 ", %" PRId32 ") in display %" PRId32, x, y,
2137 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002138 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002139 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002140 }
2141
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002142 // Figure out whether splitting will be allowed for this window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002143 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002144 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2145 // New window supports splitting, but we should never split mouse events.
2146 isSplit = !isFromMouse;
2147 } else if (isSplit) {
2148 // New window does not support splitting but we have already split events.
2149 // Ignore the new window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002150 newTouchedWindowHandle = nullptr;
2151 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002152 } else {
2153 // No window is touched, so set split to true. This will allow the next pointer down to
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002154 // be delivered to a new window which supports split touch. Pointers from a mouse device
2155 // should never be split.
2156 tempTouchState.split = isSplit = !isFromMouse;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002157 }
2158
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002159 // Update hover state.
Michael Wright3dd60e22019-03-27 22:06:44 +00002160 if (newTouchedWindowHandle != nullptr) {
Garfield Tandf26e862020-07-01 20:18:19 -07002161 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2162 newHoverWindowHandle = nullptr;
2163 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002164 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002165 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002166 }
2167
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002168 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002169 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002170 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002171 // Process the foreground window first so that it is the first to receive the event.
2172 newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002173 }
2174
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002175 if (newTouchedWindows.empty()) {
2176 ALOGI("Dropping event because there is no touchable window at (%d, %d) on display %d.",
2177 x, y, displayId);
2178 injectionResult = InputEventInjectionResult::FAILED;
2179 goto Failed;
2180 }
2181
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002182 for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
2183 const WindowInfo& info = *windowHandle->getInfo();
2184
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002185 if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002186 ALOGI("Not sending touch event to %s because it is paused",
2187 windowHandle->getName().c_str());
2188 continue;
2189 }
2190
2191 // Ensure the window has a connection and the connection is responsive
2192 const bool isResponsive = hasResponsiveConnectionLocked(*windowHandle);
2193 if (!isResponsive) {
2194 ALOGW("Not sending touch gesture to %s because it is not responsive",
2195 windowHandle->getName().c_str());
2196 continue;
2197 }
2198
2199 // Drop events that can't be trusted due to occlusion
Hani Kazmi3ce9c3a2022-04-25 09:40:23 +00002200 TouchOcclusionInfo occlusionInfo = computeTouchOcclusionInfoLocked(windowHandle, x, y);
2201 if (!isTouchTrustedLocked(occlusionInfo)) {
2202 if (DEBUG_TOUCH_OCCLUSION) {
2203 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2204 for (const auto& log : occlusionInfo.debugInfo) {
2205 ALOGD("%s", log.c_str());
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002206 }
2207 }
Hani Kazmi3ce9c3a2022-04-25 09:40:23 +00002208 ALOGW("Dropping untrusted touch event due to %s/%d",
2209 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2210 continue;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002211 }
2212
2213 // Drop touch events if requested by input feature
2214 if (shouldDropInput(entry, windowHandle)) {
2215 continue;
2216 }
2217
2218 // Set target flags.
2219 int32_t targetFlags = InputTarget::FLAG_DISPATCH_AS_IS;
2220
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002221 if (canReceiveForegroundTouches(*windowHandle->getInfo())) {
2222 // There should only be one touched window that can be "foreground" for the pointer.
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002223 targetFlags |= InputTarget::FLAG_FOREGROUND;
2224 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002225
2226 if (isSplit) {
2227 targetFlags |= InputTarget::FLAG_SPLIT;
2228 }
2229 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
2230 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2231 } else if (isWindowObscuredLocked(windowHandle)) {
2232 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2233 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002234
2235 // Update the temporary touch state.
2236 BitSet32 pointerIds;
2237 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002238 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002239 pointerIds.markBit(pointerId);
2240 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002241
2242 tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002243 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002244 } else {
2245 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2246
2247 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002248 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002249 if (DEBUG_FOCUS) {
2250 ALOGD("Dropping event because the pointer is not down or we previously "
2251 "dropped the pointer down event in display %" PRId32,
2252 displayId);
2253 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002254 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002255 goto Failed;
2256 }
2257
arthurhung6d4bed92021-03-17 11:59:33 +08002258 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002259
Michael Wrightd02c5b62014-02-10 15:10:22 -08002260 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002261 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002262 tempTouchState.isSlippery()) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002263 const int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2264 const int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002265
Prabir Pradhand65552b2021-10-07 11:23:50 -07002266 const bool isStylus = isPointerFromStylus(entry, 0 /*pointerIndex*/);
chaviw98318de2021-05-19 16:45:23 -05002267 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002268 tempTouchState.getFirstForegroundWindowHandle();
Prabir Pradhand65552b2021-10-07 11:23:50 -07002269 newTouchedWindowHandle =
2270 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState, isStylus);
Vishnu Nair062a8672021-09-03 16:07:44 -07002271
2272 // Drop touch events if requested by input feature
2273 if (newTouchedWindowHandle != nullptr &&
2274 shouldDropInput(entry, newTouchedWindowHandle)) {
2275 newTouchedWindowHandle = nullptr;
2276 }
2277
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002278 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2279 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002280 if (DEBUG_FOCUS) {
2281 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2282 oldTouchedWindowHandle->getName().c_str(),
2283 newTouchedWindowHandle->getName().c_str(), displayId);
2284 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002285 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002286 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2287 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2288 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002289
2290 // Make a slippery entrance into the new window.
2291 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002292 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002293 }
2294
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002295 int32_t targetFlags = InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
2296 if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) {
2297 targetFlags |= InputTarget::FLAG_FOREGROUND;
2298 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002299 if (isSplit) {
2300 targetFlags |= InputTarget::FLAG_SPLIT;
2301 }
2302 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2303 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002304 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2305 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002306 }
2307
2308 BitSet32 pointerIds;
2309 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002310 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002311 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002312 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002313 }
2314 }
2315 }
2316
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002317 // Update dispatching for hover enter and exit.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002318 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002319 // Let the previous window know that the hover sequence is over, unless we already did
2320 // it when dispatching it as is to newTouchedWindowHandle.
Garfield Tandf26e862020-07-01 20:18:19 -07002321 if (mLastHoverWindowHandle != nullptr &&
2322 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2323 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002324 if (DEBUG_HOVER) {
2325 ALOGD("Sending hover exit event to window %s.",
2326 mLastHoverWindowHandle->getName().c_str());
2327 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002328 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2329 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002330 }
2331
Garfield Tandf26e862020-07-01 20:18:19 -07002332 // Let the new window know that the hover sequence is starting, unless we already did it
2333 // when dispatching it as is to newTouchedWindowHandle.
2334 if (newHoverWindowHandle != nullptr &&
2335 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2336 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002337 if (DEBUG_HOVER) {
2338 ALOGD("Sending hover enter event to window %s.",
2339 newHoverWindowHandle->getName().c_str());
2340 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002341 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2342 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2343 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002344 }
2345 }
2346
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002347 // Ensure that we have at least one foreground window or at least one window that cannot be a
2348 // foreground target. If we only have windows that are not receiving foreground touches (e.g. we
2349 // only have windows getting ACTION_OUTSIDE), then drop the event, because there is no window
2350 // that is actually receiving the entire gesture.
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002351 if (std::none_of(tempTouchState.windows.begin(), tempTouchState.windows.end(),
2352 [](const TouchedWindow& touchedWindow) {
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002353 return !canReceiveForegroundTouches(
2354 *touchedWindow.windowHandle->getInfo()) ||
2355 (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0;
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002356 })) {
Siarhei Vishniakou1fb18912022-03-08 10:31:39 -08002357 ALOGI("Dropping event because there is no touched window on display %d to receive it: %s",
2358 displayId, entry.getDescription().c_str());
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002359 injectionResult = InputEventInjectionResult::FAILED;
2360 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002361 }
2362
Prabir Pradhan4df80f52022-04-05 18:33:16 +00002363 // Check permission to inject into all touched foreground windows.
2364 if (std::any_of(tempTouchState.windows.begin(), tempTouchState.windows.end(),
2365 [this, &entry](const TouchedWindow& touchedWindow) {
2366 return (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0 &&
2367 !checkInjectionPermission(touchedWindow.windowHandle,
2368 entry.injectionState);
2369 })) {
2370 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
2371 injectionPermission = INJECTION_PERMISSION_DENIED;
2372 goto Failed;
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002373 }
Prabir Pradhan4df80f52022-04-05 18:33:16 +00002374 // Permission granted to inject into all touched foreground windows.
2375 injectionPermission = INJECTION_PERMISSION_GRANTED;
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002376
Michael Wrightd02c5b62014-02-10 15:10:22 -08002377 // Check whether windows listening for outside touches are owned by the same UID. If it is
2378 // set the policy flag that we will not reveal coordinate information to this window.
2379 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002380 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002381 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002382 if (foregroundWindowHandle) {
2383 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002384 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002385 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002386 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2387 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2388 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002389 InputTarget::FLAG_ZERO_COORDS,
2390 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002391 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002392 }
2393 }
2394 }
2395 }
2396
Michael Wrightd02c5b62014-02-10 15:10:22 -08002397 // If this is the first pointer going down and the touched window has a wallpaper
2398 // then also add the touched wallpaper windows so they are locked in for the duration
2399 // of the touch gesture.
2400 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2401 // engine only supports touch events. We would need to add a mechanism similar
2402 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2403 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002404 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002405 tempTouchState.getFirstForegroundWindowHandle();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002406 if (foregroundWindowHandle &&
2407 foregroundWindowHandle->getInfo()->inputConfig.test(
2408 WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
chaviw98318de2021-05-19 16:45:23 -05002409 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002410 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002411 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2412 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002413 if (info->displayId == displayId &&
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002414 windowHandle->getInfo()->inputConfig.test(
2415 WindowInfo::InputConfig::IS_WALLPAPER)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002416 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002417 .addOrUpdateWindow(windowHandle,
2418 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2419 InputTarget::
2420 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2421 InputTarget::FLAG_DISPATCH_AS_IS,
2422 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002423 }
2424 }
2425 }
2426 }
2427
2428 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002429 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002430
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002431 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002432 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002433 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002434 }
2435
2436 // Drop the outside or hover touch windows since we will not care about them
2437 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002438 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002439
2440Failed:
Prabir Pradhan4df80f52022-04-05 18:33:16 +00002441 // Check injection permission once and for all.
2442 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
2443 if (checkInjectionPermission(nullptr, entry.injectionState)) {
2444 injectionPermission = INJECTION_PERMISSION_GRANTED;
2445 } else {
2446 injectionPermission = INJECTION_PERMISSION_DENIED;
2447 }
2448 }
2449
2450 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2451 return injectionResult;
2452 }
2453
Michael Wrightd02c5b62014-02-10 15:10:22 -08002454 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002455 if (!wrongDevice) {
2456 if (switchedDevice) {
2457 if (DEBUG_FOCUS) {
2458 ALOGD("Conflicting pointer actions: Switched to a different device.");
2459 }
2460 *outConflictingPointerActions = true;
2461 }
2462
2463 if (isHoverAction) {
2464 // Started hovering, therefore no longer down.
2465 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002466 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002467 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2468 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002469 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002470 *outConflictingPointerActions = true;
2471 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002472 tempTouchState.reset();
2473 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2474 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2475 tempTouchState.deviceId = entry.deviceId;
2476 tempTouchState.source = entry.source;
2477 tempTouchState.displayId = displayId;
2478 }
2479 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2480 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2481 // All pointers up or canceled.
2482 tempTouchState.reset();
2483 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2484 // First pointer went down.
2485 if (oldState && oldState->down) {
2486 if (DEBUG_FOCUS) {
2487 ALOGD("Conflicting pointer actions: Down received while already down.");
2488 }
2489 *outConflictingPointerActions = true;
2490 }
2491 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2492 // One pointer went up.
2493 if (isSplit) {
2494 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2495 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002496
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002497 for (size_t i = 0; i < tempTouchState.windows.size();) {
2498 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2499 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2500 touchedWindow.pointerIds.clearBit(pointerId);
2501 if (touchedWindow.pointerIds.isEmpty()) {
2502 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2503 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002504 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002505 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002506 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002507 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002508 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002509 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002510
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002511 // Save changes unless the action was scroll in which case the temporary touch
2512 // state was only valid for this one action.
2513 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2514 if (tempTouchState.displayId >= 0) {
2515 mTouchStatesByDisplay[displayId] = tempTouchState;
2516 } else {
2517 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002518 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002519 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002520
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002521 // Update hover state.
2522 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002523 }
2524
Michael Wrightd02c5b62014-02-10 15:10:22 -08002525 return injectionResult;
2526}
2527
arthurhung6d4bed92021-03-17 11:59:33 +08002528void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07002529 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2530 // have an explicit reason to support it.
2531 constexpr bool isStylus = false;
2532
chaviw98318de2021-05-19 16:45:23 -05002533 const sp<WindowInfoHandle> dropWindow =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002534 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/, isStylus,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002535 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002536 if (dropWindow) {
2537 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002538 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002539 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002540 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002541 }
2542 mDragState.reset();
2543}
2544
2545void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2546 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002547 return;
2548 }
2549
arthurhung6d4bed92021-03-17 11:59:33 +08002550 if (!mDragState->isStartDrag) {
2551 mDragState->isStartDrag = true;
2552 mDragState->isStylusButtonDownAtStart =
2553 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2554 }
2555
arthurhungb89ccb02020-12-30 16:19:01 +08002556 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2557 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2558 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2559 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002560 // Handle the special case : stylus button no longer pressed.
2561 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2562 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2563 finishDragAndDrop(entry.displayId, x, y);
2564 return;
2565 }
2566
Prabir Pradhand65552b2021-10-07 11:23:50 -07002567 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until
2568 // we have an explicit reason to support it.
2569 constexpr bool isStylus = false;
2570
chaviw98318de2021-05-19 16:45:23 -05002571 const sp<WindowInfoHandle> hoverWindowHandle =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002572 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/, isStylus,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002573 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002574 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002575 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2576 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2577 if (mDragState->dragHoverWindowHandle != nullptr) {
2578 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2579 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002580 }
arthurhung6d4bed92021-03-17 11:59:33 +08002581 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002582 }
2583 // enqueue drag location if needed.
2584 if (hoverWindowHandle != nullptr) {
2585 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2586 }
arthurhung6d4bed92021-03-17 11:59:33 +08002587 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2588 finishDragAndDrop(entry.displayId, x, y);
2589 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002590 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002591 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002592 }
2593}
2594
chaviw98318de2021-05-19 16:45:23 -05002595void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002596 int32_t targetFlags, BitSet32 pointerIds,
2597 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002598 std::vector<InputTarget>::iterator it =
2599 std::find_if(inputTargets.begin(), inputTargets.end(),
2600 [&windowHandle](const InputTarget& inputTarget) {
2601 return inputTarget.inputChannel->getConnectionToken() ==
2602 windowHandle->getToken();
2603 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002604
chaviw98318de2021-05-19 16:45:23 -05002605 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002606
2607 if (it == inputTargets.end()) {
2608 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002609 std::shared_ptr<InputChannel> inputChannel =
2610 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002611 if (inputChannel == nullptr) {
2612 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2613 return;
2614 }
2615 inputTarget.inputChannel = inputChannel;
2616 inputTarget.flags = targetFlags;
2617 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002618 const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
2619 if (displayInfoIt != mDisplayInfos.end()) {
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002620 inputTarget.displayTransform = displayInfoIt->second.transform;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002621 } else {
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00002622 ALOGE("DisplayInfo not found for window on display: %d", windowInfo->displayId);
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002623 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002624 inputTargets.push_back(inputTarget);
2625 it = inputTargets.end() - 1;
2626 }
2627
2628 ALOG_ASSERT(it->flags == targetFlags);
2629 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2630
chaviw1ff3d1e2020-07-01 15:53:47 -07002631 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002632}
2633
Michael Wright3dd60e22019-03-27 22:06:44 +00002634void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002635 int32_t displayId) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002636 auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
2637 if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
Michael Wright3dd60e22019-03-27 22:06:44 +00002638
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002639 for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
2640 InputTarget target;
2641 target.inputChannel = monitor.inputChannel;
2642 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2643 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
2644 target.displayTransform = it->second.transform;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002645 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002646 target.setDefaultPointerTransform(target.displayTransform);
2647 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002648 }
2649}
2650
Prabir Pradhan4df80f52022-04-05 18:33:16 +00002651bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
2652 const InjectionState* injectionState) {
2653 if (injectionState &&
2654 (windowHandle == nullptr ||
2655 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2656 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
2657 if (windowHandle != nullptr) {
2658 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
2659 "owned by uid %d",
2660 injectionState->injectorPid, injectionState->injectorUid,
2661 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
2662 } else {
2663 ALOGW("Permission denied: injecting event from pid %d uid %d",
2664 injectionState->injectorPid, injectionState->injectorUid);
2665 }
2666 return false;
2667 }
2668 return true;
2669}
2670
Robert Carrc9bf1d32020-04-13 17:21:08 -07002671/**
2672 * Indicate whether one window handle should be considered as obscuring
2673 * another window handle. We only check a few preconditions. Actually
2674 * checking the bounds is left to the caller.
2675 */
chaviw98318de2021-05-19 16:45:23 -05002676static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2677 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002678 // Compare by token so cloned layers aren't counted
2679 if (haveSameToken(windowHandle, otherHandle)) {
2680 return false;
2681 }
2682 auto info = windowHandle->getInfo();
2683 auto otherInfo = otherHandle->getInfo();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002684 if (otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002685 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002686 } else if (otherInfo->alpha == 0 &&
2687 otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002688 // Those act as if they were invisible, so we don't need to flag them.
2689 // We do want to potentially flag touchable windows even if they have 0
2690 // opacity, since they can consume touches and alter the effects of the
2691 // user interaction (eg. apps that rely on
2692 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2693 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2694 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002695 } else if (info->ownerUid == otherInfo->ownerUid) {
2696 // If ownerUid is the same we don't generate occlusion events as there
2697 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002698 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002699 } else if (otherInfo->inputConfig.test(gui::WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002700 return false;
2701 } else if (otherInfo->displayId != info->displayId) {
2702 return false;
2703 }
2704 return true;
2705}
2706
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002707/**
2708 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2709 * untrusted, one should check:
2710 *
2711 * 1. If result.hasBlockingOcclusion is true.
2712 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2713 * BLOCK_UNTRUSTED.
2714 *
2715 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2716 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2717 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2718 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2719 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2720 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2721 *
2722 * If neither of those is true, then it means the touch can be allowed.
2723 */
2724InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002725 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2726 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002727 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002728 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002729 TouchOcclusionInfo info;
2730 info.hasBlockingOcclusion = false;
2731 info.obscuringOpacity = 0;
2732 info.obscuringUid = -1;
2733 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002734 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002735 if (windowHandle == otherHandle) {
2736 break; // All future windows are below us. Exit early.
2737 }
chaviw98318de2021-05-19 16:45:23 -05002738 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002739 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2740 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002741 if (DEBUG_TOUCH_OCCLUSION) {
2742 info.debugInfo.push_back(
2743 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2744 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002745 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2746 // we perform the checks below to see if the touch can be propagated or not based on the
2747 // window's touch occlusion mode
2748 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2749 info.hasBlockingOcclusion = true;
2750 info.obscuringUid = otherInfo->ownerUid;
2751 info.obscuringPackage = otherInfo->packageName;
2752 break;
2753 }
2754 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2755 uint32_t uid = otherInfo->ownerUid;
2756 float opacity =
2757 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2758 // Given windows A and B:
2759 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2760 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2761 opacityByUid[uid] = opacity;
2762 if (opacity > info.obscuringOpacity) {
2763 info.obscuringOpacity = opacity;
2764 info.obscuringUid = uid;
2765 info.obscuringPackage = otherInfo->packageName;
2766 }
2767 }
2768 }
2769 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002770 if (DEBUG_TOUCH_OCCLUSION) {
2771 info.debugInfo.push_back(
2772 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2773 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002774 return info;
2775}
2776
chaviw98318de2021-05-19 16:45:23 -05002777std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002778 bool isTouchedWindow) const {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08002779 return StringPrintf(INDENT2 "* %spackage=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2780 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2781 "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
2782 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002783 isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
2784 info->ownerUid, info->id, toString(info->touchOcclusionMode).c_str(),
2785 info->alpha, info->frameLeft, info->frameTop, info->frameRight,
2786 info->frameBottom, dumpRegion(info->touchableRegion).c_str(),
2787 info->name.c_str(), info->inputConfig.string().c_str(),
Prabir Pradhan51e7db02022-02-07 06:02:57 -08002788 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002789 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002790}
2791
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002792bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2793 if (occlusionInfo.hasBlockingOcclusion) {
2794 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2795 occlusionInfo.obscuringUid);
2796 return false;
2797 }
2798 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2799 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2800 "%.2f, maximum allowed = %.2f)",
2801 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2802 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2803 return false;
2804 }
2805 return true;
2806}
2807
chaviw98318de2021-05-19 16:45:23 -05002808bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002809 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002810 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002811 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2812 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002813 if (windowHandle == otherHandle) {
2814 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002815 }
chaviw98318de2021-05-19 16:45:23 -05002816 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002817 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002818 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002819 return true;
2820 }
2821 }
2822 return false;
2823}
2824
chaviw98318de2021-05-19 16:45:23 -05002825bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002826 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002827 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2828 const WindowInfo* windowInfo = windowHandle->getInfo();
2829 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002830 if (windowHandle == otherHandle) {
2831 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002832 }
chaviw98318de2021-05-19 16:45:23 -05002833 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002834 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002835 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002836 return true;
2837 }
2838 }
2839 return false;
2840}
2841
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002842std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002843 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002844 if (applicationHandle != nullptr) {
2845 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002846 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002847 } else {
2848 return applicationHandle->getName();
2849 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002850 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002851 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002852 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002853 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002854 }
2855}
2856
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002857void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00002858 if (!isUserActivityEvent(eventEntry)) {
2859 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002860 return;
2861 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002862 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002863 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002864 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002865 const WindowInfo* info = focusedWindowHandle->getInfo();
Prabir Pradhan51e7db02022-02-07 06:02:57 -08002866 if (info->inputConfig.test(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002867 if (DEBUG_DISPATCH_CYCLE) {
2868 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2869 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002870 return;
2871 }
2872 }
2873
2874 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002875 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002876 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002877 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2878 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002879 return;
2880 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002881
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002882 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002883 eventType = USER_ACTIVITY_EVENT_TOUCH;
2884 }
2885 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002886 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002887 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002888 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2889 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002890 return;
2891 }
2892 eventType = USER_ACTIVITY_EVENT_BUTTON;
2893 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002894 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002895 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002896 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08002897 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002898 break;
2899 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002900 }
2901
Prabir Pradhancef936d2021-07-21 16:17:52 +00002902 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2903 REQUIRES(mLock) {
2904 scoped_unlock unlock(mLock);
2905 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2906 };
2907 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002908}
2909
2910void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002911 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002912 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002913 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002914 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002915 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002916 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002917 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002918 ATRACE_NAME(message.c_str());
2919 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002920 if (DEBUG_DISPATCH_CYCLE) {
2921 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2922 "globalScaleFactor=%f, pointerIds=0x%x %s",
2923 connection->getInputChannelName().c_str(), inputTarget.flags,
2924 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2925 inputTarget.getPointerInfoString().c_str());
2926 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002927
2928 // Skip this event if the connection status is not normal.
2929 // We don't want to enqueue additional outbound events if the connection is broken.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002930 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002931 if (DEBUG_DISPATCH_CYCLE) {
2932 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002933 connection->getInputChannelName().c_str(),
2934 ftl::enum_string(connection->status).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002935 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002936 return;
2937 }
2938
2939 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002940 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2941 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2942 "Entry type %s should not have FLAG_SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08002943 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002944
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002945 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002946 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002947 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002948 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002949 if (!splitMotionEntry) {
2950 return; // split event was dropped
2951 }
Arthur Hungb3307ee2021-10-14 10:57:37 +00002952 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
2953 std::string reason = std::string("reason=pointer cancel on split window");
2954 android_log_event_list(LOGTAG_INPUT_CANCEL)
2955 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
2956 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002957 if (DEBUG_FOCUS) {
2958 ALOGD("channel '%s' ~ Split motion event.",
2959 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002960 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002961 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002962 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2963 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002964 return;
2965 }
2966 }
2967
2968 // Not splitting. Enqueue dispatch entries for the event as is.
2969 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2970}
2971
2972void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002973 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002974 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002975 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002976 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002977 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002978 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002979 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002980 ATRACE_NAME(message.c_str());
2981 }
2982
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002983 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002984
2985 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002986 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002987 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002988 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002989 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002990 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002991 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002992 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002993 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002994 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002995 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002996 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002997 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002998
2999 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003000 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003001 startDispatchCycleLocked(currentTime, connection);
3002 }
3003}
3004
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003005void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003006 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003007 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003008 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003009 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003010 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
3011 connection->getInputChannelName().c_str(),
3012 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003013 ATRACE_NAME(message.c_str());
3014 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003015 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003016 if (!(inputTargetFlags & dispatchMode)) {
3017 return;
3018 }
3019 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
3020
3021 // This is a new event.
3022 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003023 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003024 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003025
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003026 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
3027 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003028 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003029 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003030 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003031 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003032 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003033 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003034 dispatchEntry->resolvedAction = keyEntry.action;
3035 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003036
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003037 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
3038 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003039 if (DEBUG_DISPATCH_CYCLE) {
3040 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
3041 "event",
3042 connection->getInputChannelName().c_str());
3043 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003044 return; // skip the inconsistent event
3045 }
3046 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003047 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003048
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003049 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003050 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003051 // Assign a default value to dispatchEntry that will never be generated by InputReader,
3052 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
3053 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
3054 static_cast<int32_t>(IdGenerator::Source::OTHER);
3055 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003056 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3057 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
3058 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
3059 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
3060 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
3061 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3062 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
3063 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
3064 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
3065 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
3066 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003067 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003068 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003069 }
3070 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003071 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3072 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003073 if (DEBUG_DISPATCH_CYCLE) {
3074 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
3075 "enter event",
3076 connection->getInputChannelName().c_str());
3077 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003078 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
3079 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003080 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3081 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003082
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003083 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003084 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
3085 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3086 }
3087 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
3088 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3089 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003090
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003091 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
3092 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003093 if (DEBUG_DISPATCH_CYCLE) {
3094 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
3095 "event",
3096 connection->getInputChannelName().c_str());
3097 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003098 return; // skip the inconsistent event
3099 }
3100
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003101 dispatchEntry->resolvedEventId =
3102 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
3103 ? mIdGenerator.nextId()
3104 : motionEntry.id;
3105 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
3106 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3107 ") to MotionEvent(id=0x%" PRIx32 ").",
3108 motionEntry.id, dispatchEntry->resolvedEventId);
3109 ATRACE_NAME(message.c_str());
3110 }
3111
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003112 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3113 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
3114 // Skip reporting pointer down outside focus to the policy.
3115 break;
3116 }
3117
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003118 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003119 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003120
3121 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003122 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003123 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003124 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003125 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3126 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003127 break;
3128 }
Chris Yef59a2f42020-10-16 12:55:26 -07003129 case EventEntry::Type::SENSOR: {
3130 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3131 break;
3132 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003133 case EventEntry::Type::CONFIGURATION_CHANGED:
3134 case EventEntry::Type::DEVICE_RESET: {
3135 LOG_ALWAYS_FATAL("%s events should not go to apps",
Dominik Laskowski75788452021-02-09 18:51:25 -08003136 ftl::enum_string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003137 break;
3138 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003139 }
3140
3141 // Remember that we are waiting for this dispatch to complete.
3142 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003143 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003144 }
3145
3146 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003147 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003148 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003149}
3150
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003151/**
3152 * This function is purely for debugging. It helps us understand where the user interaction
3153 * was taking place. For example, if user is touching launcher, we will see a log that user
3154 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3155 * We will see both launcher and wallpaper in that list.
3156 * Once the interaction with a particular set of connections starts, no new logs will be printed
3157 * until the set of interacted connections changes.
3158 *
3159 * The following items are skipped, to reduce the logspam:
3160 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3161 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3162 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3163 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3164 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003165 */
3166void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3167 const std::vector<InputTarget>& targets) {
3168 // Skip ACTION_UP events, and all events other than keys and motions
3169 if (entry.type == EventEntry::Type::KEY) {
3170 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3171 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3172 return;
3173 }
3174 } else if (entry.type == EventEntry::Type::MOTION) {
3175 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3176 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3177 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3178 return;
3179 }
3180 } else {
3181 return; // Not a key or a motion
3182 }
3183
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003184 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003185 std::vector<sp<Connection>> newConnections;
3186 for (const InputTarget& target : targets) {
3187 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3188 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3189 continue; // Skip windows that receive ACTION_OUTSIDE
3190 }
3191
3192 sp<IBinder> token = target.inputChannel->getConnectionToken();
3193 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003194 if (connection == nullptr) {
3195 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003196 }
3197 newConnectionTokens.insert(std::move(token));
3198 newConnections.emplace_back(connection);
3199 }
3200 if (newConnectionTokens == mInteractionConnectionTokens) {
3201 return; // no change
3202 }
3203 mInteractionConnectionTokens = newConnectionTokens;
3204
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003205 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003206 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003207 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003208 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003209 std::string message = "Interaction with: " + targetList;
3210 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003211 message += "<none>";
3212 }
3213 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3214}
3215
chaviwfd6d3512019-03-25 13:23:49 -07003216void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003217 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003218 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003219 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3220 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003221 return;
3222 }
3223
Vishnu Nairc519ff72021-01-21 08:23:08 -08003224 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003225 if (focusedToken == token) {
3226 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003227 return;
3228 }
3229
Prabir Pradhancef936d2021-07-21 16:17:52 +00003230 auto command = [this, token]() REQUIRES(mLock) {
3231 scoped_unlock unlock(mLock);
3232 mPolicy->onPointerDownOutsideFocus(token);
3233 };
3234 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003235}
3236
3237void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003238 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003239 if (ATRACE_ENABLED()) {
3240 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003241 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003242 ATRACE_NAME(message.c_str());
3243 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003244 if (DEBUG_DISPATCH_CYCLE) {
3245 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3246 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003247
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003248 while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003249 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003250 dispatchEntry->deliveryTime = currentTime;
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08003251 const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003252 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003253
3254 // Publish the event.
3255 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003256 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3257 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003258 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003259 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3260 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003261
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003262 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003263 status = connection->inputPublisher
3264 .publishKeyEvent(dispatchEntry->seq,
3265 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3266 keyEntry.source, keyEntry.displayId,
3267 std::move(hmac), dispatchEntry->resolvedAction,
3268 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3269 keyEntry.scanCode, keyEntry.metaState,
3270 keyEntry.repeatCount, keyEntry.downTime,
3271 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003272 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003273 }
3274
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003275 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003276 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003277
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003278 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003279 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003280
chaviw82357092020-01-28 13:13:06 -08003281 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003282 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003283 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3284 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003285 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003286 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3287 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003288 // Don't apply window scale here since we don't want scale to affect raw
3289 // coordinates. The scale will be sent back to the client and applied
3290 // later when requesting relative coordinates.
3291 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3292 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003293 }
3294 usingCoords = scaledCoords;
3295 }
3296 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003297 // We don't want the dispatch target to know.
3298 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003299 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003300 scaledCoords[i].clear();
3301 }
3302 usingCoords = scaledCoords;
3303 }
3304 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003305
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003306 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003307
3308 // Publish the motion event.
3309 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003310 .publishMotionEvent(dispatchEntry->seq,
3311 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003312 motionEntry.deviceId, motionEntry.source,
3313 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003314 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003315 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003316 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003317 motionEntry.edgeFlags, motionEntry.metaState,
3318 motionEntry.buttonState,
3319 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003320 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003321 motionEntry.xPrecision, motionEntry.yPrecision,
3322 motionEntry.xCursorPosition,
3323 motionEntry.yCursorPosition,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003324 dispatchEntry->rawTransform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003325 motionEntry.downTime, motionEntry.eventTime,
3326 motionEntry.pointerCount,
3327 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003328 break;
3329 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003330
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003331 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003332 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003333 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003334 focusEntry.id,
Antonio Kantek3cfec7b2021-11-05 18:26:17 -07003335 focusEntry.hasFocus);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003336 break;
3337 }
3338
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003339 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3340 const TouchModeEntry& touchModeEntry =
3341 static_cast<const TouchModeEntry&>(eventEntry);
3342 status = connection->inputPublisher
3343 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3344 touchModeEntry.inTouchMode);
3345
3346 break;
3347 }
3348
Prabir Pradhan99987712020-11-10 18:43:05 -08003349 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3350 const auto& captureEntry =
3351 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3352 status = connection->inputPublisher
3353 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003354 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003355 break;
3356 }
3357
arthurhungb89ccb02020-12-30 16:19:01 +08003358 case EventEntry::Type::DRAG: {
3359 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3360 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3361 dragEntry.id, dragEntry.x,
3362 dragEntry.y,
3363 dragEntry.isExiting);
3364 break;
3365 }
3366
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003367 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003368 case EventEntry::Type::DEVICE_RESET:
3369 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003370 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003371 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003372 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003373 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003374 }
3375
3376 // Check the result.
3377 if (status) {
3378 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003379 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003380 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003381 "This is unexpected because the wait queue is empty, so the pipe "
3382 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003383 "event to it, status=%s(%d)",
3384 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3385 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003386 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3387 } else {
3388 // Pipe is full and we are waiting for the app to finish process some events
3389 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003390 if (DEBUG_DISPATCH_CYCLE) {
3391 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3392 "waiting for the application to catch up",
3393 connection->getInputChannelName().c_str());
3394 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003395 }
3396 } else {
3397 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003398 "status=%s(%d)",
3399 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3400 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003401 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3402 }
3403 return;
3404 }
3405
3406 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003407 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3408 connection->outboundQueue.end(),
3409 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003410 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003411 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003412 if (connection->responsive) {
3413 mAnrTracker.insert(dispatchEntry->timeoutTime,
3414 connection->inputChannel->getConnectionToken());
3415 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003416 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003417 }
3418}
3419
chaviw09c8d2d2020-08-24 15:48:26 -07003420std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3421 size_t size;
3422 switch (event.type) {
3423 case VerifiedInputEvent::Type::KEY: {
3424 size = sizeof(VerifiedKeyEvent);
3425 break;
3426 }
3427 case VerifiedInputEvent::Type::MOTION: {
3428 size = sizeof(VerifiedMotionEvent);
3429 break;
3430 }
3431 }
3432 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3433 return mHmacKeyManager.sign(start, size);
3434}
3435
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003436const std::array<uint8_t, 32> InputDispatcher::getSignature(
3437 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003438 const int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3439 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003440 // Only sign events up and down events as the purely move events
3441 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003442 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003443 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003444
3445 VerifiedMotionEvent verifiedEvent =
3446 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3447 verifiedEvent.actionMasked = actionMasked;
3448 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3449 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003450}
3451
3452const std::array<uint8_t, 32> InputDispatcher::getSignature(
3453 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3454 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3455 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3456 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003457 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003458}
3459
Michael Wrightd02c5b62014-02-10 15:10:22 -08003460void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003461 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003462 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003463 if (DEBUG_DISPATCH_CYCLE) {
3464 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3465 connection->getInputChannelName().c_str(), seq, toString(handled));
3466 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003467
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003468 if (connection->status == Connection::Status::BROKEN ||
3469 connection->status == Connection::Status::ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003470 return;
3471 }
3472
3473 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003474 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3475 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3476 };
3477 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003478}
3479
3480void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003481 const sp<Connection>& connection,
3482 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003483 if (DEBUG_DISPATCH_CYCLE) {
3484 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3485 connection->getInputChannelName().c_str(), toString(notify));
3486 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003487
3488 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003489 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003490 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003491 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003492 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003493
3494 // The connection appears to be unrecoverably broken.
3495 // Ignore already broken or zombie connections.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003496 if (connection->status == Connection::Status::NORMAL) {
3497 connection->status = Connection::Status::BROKEN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003498
3499 if (notify) {
3500 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003501 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3502 connection->getInputChannelName().c_str());
3503
3504 auto command = [this, connection]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003505 scoped_unlock unlock(mLock);
3506 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3507 };
3508 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003509 }
3510 }
3511}
3512
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003513void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3514 while (!queue.empty()) {
3515 DispatchEntry* dispatchEntry = queue.front();
3516 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003517 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003518 }
3519}
3520
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003521void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003522 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003523 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003524 }
3525 delete dispatchEntry;
3526}
3527
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003528int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3529 std::scoped_lock _l(mLock);
3530 sp<Connection> connection = getConnectionLocked(connectionToken);
3531 if (connection == nullptr) {
3532 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3533 connectionToken.get(), events);
3534 return 0; // remove the callback
3535 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003536
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003537 bool notify;
3538 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3539 if (!(events & ALOOPER_EVENT_INPUT)) {
3540 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3541 "events=0x%x",
3542 connection->getInputChannelName().c_str(), events);
3543 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003544 }
3545
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003546 nsecs_t currentTime = now();
3547 bool gotOne = false;
3548 status_t status = OK;
3549 for (;;) {
3550 Result<InputPublisher::ConsumerResponse> result =
3551 connection->inputPublisher.receiveConsumerResponse();
3552 if (!result.ok()) {
3553 status = result.error().code();
3554 break;
3555 }
3556
3557 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3558 const InputPublisher::Finished& finish =
3559 std::get<InputPublisher::Finished>(*result);
3560 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3561 finish.consumeTime);
3562 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003563 if (shouldReportMetricsForConnection(*connection)) {
3564 const InputPublisher::Timeline& timeline =
3565 std::get<InputPublisher::Timeline>(*result);
3566 mLatencyTracker
3567 .trackGraphicsLatency(timeline.inputEventId,
3568 connection->inputChannel->getConnectionToken(),
3569 std::move(timeline.graphicsTimeline));
3570 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003571 }
3572 gotOne = true;
3573 }
3574 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003575 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003576 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003577 return 1;
3578 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003579 }
3580
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003581 notify = status != DEAD_OBJECT || !connection->monitor;
3582 if (notify) {
3583 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3584 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3585 status);
3586 }
3587 } else {
3588 // Monitor channels are never explicitly unregistered.
3589 // We do it automatically when the remote endpoint is closed so don't warn about them.
3590 const bool stillHaveWindowHandle =
3591 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3592 notify = !connection->monitor && stillHaveWindowHandle;
3593 if (notify) {
3594 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3595 connection->getInputChannelName().c_str(), events);
3596 }
3597 }
3598
3599 // Remove the channel.
3600 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3601 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003602}
3603
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003604void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003605 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003606 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003607 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003608 }
3609}
3610
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003611void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003612 const CancelationOptions& options) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08003613 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003614 for (const Monitor& monitor : monitors) {
3615 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003616 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003617 }
3618}
3619
Michael Wrightd02c5b62014-02-10 15:10:22 -08003620void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003621 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003622 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003623 if (connection == nullptr) {
3624 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003625 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003626
3627 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003628}
3629
3630void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3631 const sp<Connection>& connection, const CancelationOptions& options) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003632 if (connection->status == Connection::Status::BROKEN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003633 return;
3634 }
3635
3636 nsecs_t currentTime = now();
3637
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003638 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003639 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003640
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003641 if (cancelationEvents.empty()) {
3642 return;
3643 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003644 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3645 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3646 "with reality: %s, mode=%d.",
3647 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3648 options.mode);
3649 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003650
Arthur Hungb3307ee2021-10-14 10:57:37 +00003651 std::string reason = std::string("reason=").append(options.reason);
3652 android_log_event_list(LOGTAG_INPUT_CANCEL)
3653 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3654
Svet Ganov5d3bc372020-01-26 23:11:07 -08003655 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003656 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003657 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3658 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003659 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003660 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003661 target.globalScaleFactor = windowInfo->globalScaleFactor;
3662 }
3663 target.inputChannel = connection->inputChannel;
3664 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3665
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003666 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003667 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003668 switch (cancelationEventEntry->type) {
3669 case EventEntry::Type::KEY: {
3670 logOutboundKeyDetails("cancel - ",
3671 static_cast<const KeyEntry&>(*cancelationEventEntry));
3672 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003673 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003674 case EventEntry::Type::MOTION: {
3675 logOutboundMotionDetails("cancel - ",
3676 static_cast<const MotionEntry&>(*cancelationEventEntry));
3677 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003678 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003679 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003680 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003681 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3682 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003683 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08003684 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003685 break;
3686 }
3687 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003688 case EventEntry::Type::DEVICE_RESET:
3689 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003690 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003691 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003692 break;
3693 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003694 }
3695
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003696 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3697 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003698 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003699
3700 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003701}
3702
Svet Ganov5d3bc372020-01-26 23:11:07 -08003703void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3704 const sp<Connection>& connection) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003705 if (connection->status == Connection::Status::BROKEN) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003706 return;
3707 }
3708
3709 nsecs_t currentTime = now();
3710
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003711 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003712 connection->inputState.synthesizePointerDownEvents(currentTime);
3713
3714 if (downEvents.empty()) {
3715 return;
3716 }
3717
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003718 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003719 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3720 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003721 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003722
3723 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003724 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003725 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3726 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003727 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003728 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003729 target.globalScaleFactor = windowInfo->globalScaleFactor;
3730 }
3731 target.inputChannel = connection->inputChannel;
3732 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3733
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003734 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003735 switch (downEventEntry->type) {
3736 case EventEntry::Type::MOTION: {
3737 logOutboundMotionDetails("down - ",
3738 static_cast<const MotionEntry&>(*downEventEntry));
3739 break;
3740 }
3741
3742 case EventEntry::Type::KEY:
3743 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003744 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08003745 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003746 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003747 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003748 case EventEntry::Type::SENSOR:
3749 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003750 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003751 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003752 break;
3753 }
3754 }
3755
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003756 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3757 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003758 }
3759
3760 startDispatchCycleLocked(currentTime, connection);
3761}
3762
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003763std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3764 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003765 ALOG_ASSERT(pointerIds.value != 0);
3766
3767 uint32_t splitPointerIndexMap[MAX_POINTERS];
3768 PointerProperties splitPointerProperties[MAX_POINTERS];
3769 PointerCoords splitPointerCoords[MAX_POINTERS];
3770
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003771 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003772 uint32_t splitPointerCount = 0;
3773
3774 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003775 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003776 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003777 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003778 uint32_t pointerId = uint32_t(pointerProperties.id);
3779 if (pointerIds.hasBit(pointerId)) {
3780 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3781 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3782 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003783 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003784 splitPointerCount += 1;
3785 }
3786 }
3787
3788 if (splitPointerCount != pointerIds.count()) {
3789 // This is bad. We are missing some of the pointers that we expected to deliver.
3790 // Most likely this indicates that we received an ACTION_MOVE events that has
3791 // different pointer ids than we expected based on the previous ACTION_DOWN
3792 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3793 // in this way.
3794 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003795 "we expected there to be %d pointers. This probably means we received "
3796 "a broken sequence of pointer ids from the input device.",
3797 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003798 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003799 }
3800
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003801 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003802 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003803 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3804 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003805 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3806 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003807 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003808 uint32_t pointerId = uint32_t(pointerProperties.id);
3809 if (pointerIds.hasBit(pointerId)) {
3810 if (pointerIds.count() == 1) {
3811 // The first/last pointer went down/up.
3812 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003813 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003814 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3815 ? AMOTION_EVENT_ACTION_CANCEL
3816 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003817 } else {
3818 // A secondary pointer went down/up.
3819 uint32_t splitPointerIndex = 0;
3820 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3821 splitPointerIndex += 1;
3822 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003823 action = maskedAction |
3824 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003825 }
3826 } else {
3827 // An unrelated pointer changed.
3828 action = AMOTION_EVENT_ACTION_MOVE;
3829 }
3830 }
3831
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003832 int32_t newId = mIdGenerator.nextId();
3833 if (ATRACE_ENABLED()) {
3834 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3835 ") to MotionEvent(id=0x%" PRIx32 ").",
3836 originalMotionEntry.id, newId);
3837 ATRACE_NAME(message.c_str());
3838 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003839 std::unique_ptr<MotionEntry> splitMotionEntry =
3840 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3841 originalMotionEntry.deviceId, originalMotionEntry.source,
3842 originalMotionEntry.displayId,
3843 originalMotionEntry.policyFlags, action,
3844 originalMotionEntry.actionButton,
3845 originalMotionEntry.flags, originalMotionEntry.metaState,
3846 originalMotionEntry.buttonState,
3847 originalMotionEntry.classification,
3848 originalMotionEntry.edgeFlags,
3849 originalMotionEntry.xPrecision,
3850 originalMotionEntry.yPrecision,
3851 originalMotionEntry.xCursorPosition,
3852 originalMotionEntry.yCursorPosition,
3853 originalMotionEntry.downTime, splitPointerCount,
Prabir Pradhan5beda762021-12-10 09:30:08 +00003854 splitPointerProperties, splitPointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003855
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003856 if (originalMotionEntry.injectionState) {
3857 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003858 splitMotionEntry->injectionState->refCount += 1;
3859 }
3860
3861 return splitMotionEntry;
3862}
3863
3864void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003865 if (DEBUG_INBOUND_EVENT_DETAILS) {
3866 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3867 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003868
Antonio Kantekf16f2832021-09-28 04:39:20 +00003869 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003870 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003871 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003872
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003873 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3874 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3875 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003876 } // release lock
3877
3878 if (needWake) {
3879 mLooper->wake();
3880 }
3881}
3882
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003883/**
3884 * If one of the meta shortcuts is detected, process them here:
3885 * Meta + Backspace -> generate BACK
3886 * Meta + Enter -> generate HOME
3887 * This will potentially overwrite keyCode and metaState.
3888 */
3889void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003890 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003891 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3892 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3893 if (keyCode == AKEYCODE_DEL) {
3894 newKeyCode = AKEYCODE_BACK;
3895 } else if (keyCode == AKEYCODE_ENTER) {
3896 newKeyCode = AKEYCODE_HOME;
3897 }
3898 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003899 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003900 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003901 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003902 keyCode = newKeyCode;
3903 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3904 }
3905 } else if (action == AKEY_EVENT_ACTION_UP) {
3906 // In order to maintain a consistent stream of up and down events, check to see if the key
3907 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3908 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003909 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003910 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003911 auto replacementIt = mReplacedKeys.find(replacement);
3912 if (replacementIt != mReplacedKeys.end()) {
3913 keyCode = replacementIt->second;
3914 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003915 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3916 }
3917 }
3918}
3919
Michael Wrightd02c5b62014-02-10 15:10:22 -08003920void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003921 if (DEBUG_INBOUND_EVENT_DETAILS) {
3922 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3923 "policyFlags=0x%x, action=0x%x, "
3924 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3925 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3926 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3927 args->downTime);
3928 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003929 if (!validateKeyEvent(args->action)) {
3930 return;
3931 }
3932
3933 uint32_t policyFlags = args->policyFlags;
3934 int32_t flags = args->flags;
3935 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003936 // InputDispatcher tracks and generates key repeats on behalf of
3937 // whatever notifies it, so repeatCount should always be set to 0
3938 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003939 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3940 policyFlags |= POLICY_FLAG_VIRTUAL;
3941 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3942 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003943 if (policyFlags & POLICY_FLAG_FUNCTION) {
3944 metaState |= AMETA_FUNCTION_ON;
3945 }
3946
3947 policyFlags |= POLICY_FLAG_TRUSTED;
3948
Michael Wright78f24442014-08-06 15:55:28 -07003949 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003950 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003951
Michael Wrightd02c5b62014-02-10 15:10:22 -08003952 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003953 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003954 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3955 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003956
Michael Wright2b3c3302018-03-02 17:19:13 +00003957 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003958 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003959 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3960 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003961 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003962 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003963
Antonio Kantekf16f2832021-09-28 04:39:20 +00003964 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003965 { // acquire lock
3966 mLock.lock();
3967
3968 if (shouldSendKeyToInputFilterLocked(args)) {
3969 mLock.unlock();
3970
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003971 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003972 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3973 return; // event was consumed by the filter
3974 }
3975
3976 mLock.lock();
3977 }
3978
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003979 std::unique_ptr<KeyEntry> newEntry =
3980 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3981 args->displayId, policyFlags, args->action, flags,
3982 keyCode, args->scanCode, metaState, repeatCount,
3983 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003984
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003985 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003986 mLock.unlock();
3987 } // release lock
3988
3989 if (needWake) {
3990 mLooper->wake();
3991 }
3992}
3993
3994bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3995 return mInputFilterEnabled;
3996}
3997
3998void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003999 if (DEBUG_INBOUND_EVENT_DETAILS) {
4000 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4001 "displayId=%" PRId32 ", policyFlags=0x%x, "
4002 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
4003 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
4004 "yCursorPosition=%f, downTime=%" PRId64,
4005 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
4006 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
4007 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
4008 args->xCursorPosition, args->yCursorPosition, args->downTime);
4009 for (uint32_t i = 0; i < args->pointerCount; i++) {
4010 ALOGD(" Pointer %d: id=%d, toolType=%d, "
4011 "x=%f, y=%f, pressure=%f, size=%f, "
4012 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
4013 "orientation=%f",
4014 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
4015 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
4016 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
4017 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
4018 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
4019 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
4020 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
4021 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
4022 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
4023 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
4024 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004025 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004026 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
4027 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004028 return;
4029 }
4030
4031 uint32_t policyFlags = args->policyFlags;
4032 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004033
4034 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08004035 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004036 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4037 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004038 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004039 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004040
Antonio Kantekf16f2832021-09-28 04:39:20 +00004041 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004042 { // acquire lock
4043 mLock.lock();
4044
4045 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004046 ui::Transform displayTransform;
4047 if (const auto it = mDisplayInfos.find(args->displayId); it != mDisplayInfos.end()) {
4048 displayTransform = it->second.transform;
4049 }
4050
Michael Wrightd02c5b62014-02-10 15:10:22 -08004051 mLock.unlock();
4052
4053 MotionEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08004054 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
4055 args->action, args->actionButton, args->flags, args->edgeFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07004056 args->metaState, args->buttonState, args->classification,
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004057 displayTransform, args->xPrecision, args->yPrecision,
4058 args->xCursorPosition, args->yCursorPosition, displayTransform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07004059 args->downTime, args->eventTime, args->pointerCount,
4060 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004061
4062 policyFlags |= POLICY_FLAG_FILTERED;
4063 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
4064 return; // event was consumed by the filter
4065 }
4066
4067 mLock.lock();
4068 }
4069
4070 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004071 std::unique_ptr<MotionEntry> newEntry =
4072 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
4073 args->source, args->displayId, policyFlags,
4074 args->action, args->actionButton, args->flags,
4075 args->metaState, args->buttonState,
4076 args->classification, args->edgeFlags,
4077 args->xPrecision, args->yPrecision,
4078 args->xCursorPosition, args->yCursorPosition,
4079 args->downTime, args->pointerCount,
Prabir Pradhan5beda762021-12-10 09:30:08 +00004080 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004081
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004082 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4083 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
4084 !mInputFilterEnabled) {
4085 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
4086 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
4087 }
4088
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004089 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004090 mLock.unlock();
4091 } // release lock
4092
4093 if (needWake) {
4094 mLooper->wake();
4095 }
4096}
4097
Chris Yef59a2f42020-10-16 12:55:26 -07004098void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004099 if (DEBUG_INBOUND_EVENT_DETAILS) {
4100 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4101 " sensorType=%s",
4102 args->id, args->eventTime, args->deviceId, args->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08004103 ftl::enum_string(args->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004104 }
Chris Yef59a2f42020-10-16 12:55:26 -07004105
Antonio Kantekf16f2832021-09-28 04:39:20 +00004106 bool needWake = false;
Chris Yef59a2f42020-10-16 12:55:26 -07004107 { // acquire lock
4108 mLock.lock();
4109
4110 // Just enqueue a new sensor event.
4111 std::unique_ptr<SensorEntry> newEntry =
4112 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
4113 args->source, 0 /* policyFlags*/, args->hwTimestamp,
4114 args->sensorType, args->accuracy,
4115 args->accuracyChanged, args->values);
4116
4117 needWake = enqueueInboundEventLocked(std::move(newEntry));
4118 mLock.unlock();
4119 } // release lock
4120
4121 if (needWake) {
4122 mLooper->wake();
4123 }
4124}
4125
Chris Yefb552902021-02-03 17:18:37 -08004126void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004127 if (DEBUG_INBOUND_EVENT_DETAILS) {
4128 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
4129 args->deviceId, args->isOn);
4130 }
Chris Yefb552902021-02-03 17:18:37 -08004131 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
4132}
4133
Michael Wrightd02c5b62014-02-10 15:10:22 -08004134bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08004135 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004136}
4137
4138void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004139 if (DEBUG_INBOUND_EVENT_DETAILS) {
4140 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4141 "switchMask=0x%08x",
4142 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
4143 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004144
4145 uint32_t policyFlags = args->policyFlags;
4146 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004147 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004148}
4149
4150void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004151 if (DEBUG_INBOUND_EVENT_DETAILS) {
4152 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
4153 args->deviceId);
4154 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004155
Antonio Kantekf16f2832021-09-28 04:39:20 +00004156 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004157 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004158 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004159
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004160 std::unique_ptr<DeviceResetEntry> newEntry =
4161 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
4162 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004163 } // release lock
4164
4165 if (needWake) {
4166 mLooper->wake();
4167 }
4168}
4169
Prabir Pradhan7e186182020-11-10 13:56:45 -08004170void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004171 if (DEBUG_INBOUND_EVENT_DETAILS) {
4172 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004173 args->request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004174 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004175
Antonio Kantekf16f2832021-09-28 04:39:20 +00004176 bool needWake = false;
Prabir Pradhan99987712020-11-10 18:43:05 -08004177 { // acquire lock
4178 std::scoped_lock _l(mLock);
4179 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004180 args->request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004181 needWake = enqueueInboundEventLocked(std::move(entry));
4182 } // release lock
4183
4184 if (needWake) {
4185 mLooper->wake();
4186 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004187}
4188
Prabir Pradhan4df80f52022-04-05 18:33:16 +00004189InputEventInjectionResult InputDispatcher::injectInputEvent(
4190 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4191 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004192 if (DEBUG_INBOUND_EVENT_DETAILS) {
Prabir Pradhan4df80f52022-04-05 18:33:16 +00004193 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
4194 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4195 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004196 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004197 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004198
Prabir Pradhan4df80f52022-04-05 18:33:16 +00004199 policyFlags |= POLICY_FLAG_INJECTED;
4200 if (hasInjectionPermission(injectorPid, injectorUid)) {
4201 policyFlags |= POLICY_FLAG_TRUSTED;
4202 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004203
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004204 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004205 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4206 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4207 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4208 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4209 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004210 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004211 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004212 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004213 }
4214
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004215 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004216 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004217 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004218 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4219 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004220 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004221 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004222 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004223
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004224 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004225 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4226 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4227 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004228 int32_t keyCode = incomingKey.getKeyCode();
4229 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004230 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004231 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004232 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004233 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004234 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4235 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4236 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004237
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004238 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4239 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004240 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004241
4242 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4243 android::base::Timer t;
4244 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4245 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4246 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4247 std::to_string(t.duration().count()).c_str());
4248 }
4249 }
4250
4251 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004252 std::unique_ptr<KeyEntry> injectedEntry =
4253 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004254 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004255 incomingKey.getDisplayId(), policyFlags, action,
4256 flags, keyCode, incomingKey.getScanCode(), metaState,
4257 incomingKey.getRepeatCount(),
4258 incomingKey.getDownTime());
4259 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004260 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004261 }
4262
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004263 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004264 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004265 const int32_t action = motionEvent.getAction();
4266 const bool isPointerEvent =
4267 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4268 // If a pointer event has no displayId specified, inject it to the default display.
4269 const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
4270 ? ADISPLAY_ID_DEFAULT
4271 : event->getDisplayId();
4272 const size_t pointerCount = motionEvent.getPointerCount();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004273 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004274 const int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004275 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004276 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004277 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004278 }
4279
4280 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004281 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004282 android::base::Timer t;
4283 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4284 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4285 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4286 std::to_string(t.duration().count()).c_str());
4287 }
4288 }
4289
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004290 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4291 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4292 }
4293
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004294 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004295 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4296 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004297 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004298 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4299 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004300 displayId, policyFlags, action, actionButton,
4301 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004302 motionEvent.getButtonState(),
4303 motionEvent.getClassification(),
4304 motionEvent.getEdgeFlags(),
4305 motionEvent.getXPrecision(),
4306 motionEvent.getYPrecision(),
4307 motionEvent.getRawXCursorPosition(),
4308 motionEvent.getRawYCursorPosition(),
4309 motionEvent.getDownTime(), uint32_t(pointerCount),
Prabir Pradhan5beda762021-12-10 09:30:08 +00004310 pointerProperties, samplePointerCoords);
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004311 transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004312 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004313 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004314 sampleEventTimes += 1;
4315 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004316 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004317 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4318 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004319 displayId, policyFlags, action, actionButton,
4320 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004321 motionEvent.getButtonState(),
4322 motionEvent.getClassification(),
4323 motionEvent.getEdgeFlags(),
4324 motionEvent.getXPrecision(),
4325 motionEvent.getYPrecision(),
4326 motionEvent.getRawXCursorPosition(),
4327 motionEvent.getRawYCursorPosition(),
4328 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004329 uint32_t(pointerCount), pointerProperties,
Prabir Pradhan5beda762021-12-10 09:30:08 +00004330 samplePointerCoords);
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004331 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
4332 motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004333 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004334 }
4335 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004336 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004337
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004338 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004339 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004340 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004341 }
4342
Prabir Pradhan4df80f52022-04-05 18:33:16 +00004343 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004344 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004345 injectionState->injectionIsAsync = true;
4346 }
4347
4348 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004349 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004350
4351 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004352 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004353 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004354 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004355 }
4356
4357 mLock.unlock();
4358
4359 if (needWake) {
4360 mLooper->wake();
4361 }
4362
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004363 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004364 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004365 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004366
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004367 if (syncMode == InputEventInjectionSync::NONE) {
4368 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004369 } else {
4370 for (;;) {
4371 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004372 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004373 break;
4374 }
4375
4376 nsecs_t remainingTimeout = endTime - now();
4377 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004378 if (DEBUG_INJECTION) {
4379 ALOGD("injectInputEvent - Timed out waiting for injection result "
4380 "to become available.");
4381 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004382 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004383 break;
4384 }
4385
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004386 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004387 }
4388
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004389 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4390 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004391 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004392 if (DEBUG_INJECTION) {
4393 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4394 injectionState->pendingForegroundDispatches);
4395 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004396 nsecs_t remainingTimeout = endTime - now();
4397 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004398 if (DEBUG_INJECTION) {
4399 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4400 "dispatches to finish.");
4401 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004402 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004403 break;
4404 }
4405
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004406 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004407 }
4408 }
4409 }
4410
4411 injectionState->release();
4412 } // release lock
4413
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004414 if (DEBUG_INJECTION) {
Prabir Pradhan4df80f52022-04-05 18:33:16 +00004415 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
4416 injectionResult, injectorPid, injectorUid);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004417 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004418
4419 return injectionResult;
4420}
4421
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004422std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004423 std::array<uint8_t, 32> calculatedHmac;
4424 std::unique_ptr<VerifiedInputEvent> result;
4425 switch (event.getType()) {
4426 case AINPUT_EVENT_TYPE_KEY: {
4427 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4428 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4429 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004430 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004431 break;
4432 }
4433 case AINPUT_EVENT_TYPE_MOTION: {
4434 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4435 VerifiedMotionEvent verifiedMotionEvent =
4436 verifiedMotionEventFromMotionEvent(motionEvent);
4437 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004438 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004439 break;
4440 }
4441 default: {
4442 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4443 return nullptr;
4444 }
4445 }
4446 if (calculatedHmac == INVALID_HMAC) {
4447 return nullptr;
4448 }
4449 if (calculatedHmac != event.getHmac()) {
4450 return nullptr;
4451 }
4452 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004453}
4454
Prabir Pradhan4df80f52022-04-05 18:33:16 +00004455bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
4456 return injectorUid == 0 ||
4457 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
4458}
4459
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004460void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004461 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004462 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004463 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004464 if (DEBUG_INJECTION) {
Prabir Pradhan4df80f52022-04-05 18:33:16 +00004465 ALOGD("Setting input event injection result to %d. "
4466 "injectorPid=%d, injectorUid=%d",
4467 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004468 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004469
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004470 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004471 // Log the outcome since the injector did not wait for the injection result.
4472 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004473 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004474 ALOGV("Asynchronous input event injection succeeded.");
4475 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004476 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004477 ALOGW("Asynchronous input event injection failed.");
4478 break;
Prabir Pradhan4df80f52022-04-05 18:33:16 +00004479 case InputEventInjectionResult::PERMISSION_DENIED:
4480 ALOGW("Asynchronous input event injection permission denied.");
4481 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004482 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004483 ALOGW("Asynchronous input event injection timed out.");
4484 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004485 case InputEventInjectionResult::PENDING:
4486 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4487 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004488 }
4489 }
4490
4491 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004492 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004493 }
4494}
4495
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004496void InputDispatcher::transformMotionEntryForInjectionLocked(
4497 MotionEntry& entry, const ui::Transform& injectedTransform) const {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004498 // Input injection works in the logical display coordinate space, but the input pipeline works
4499 // display space, so we need to transform the injected events accordingly.
4500 const auto it = mDisplayInfos.find(entry.displayId);
4501 if (it == mDisplayInfos.end()) return;
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004502 const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004503
4504 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Prabir Pradhan8e6ce222022-02-24 09:08:54 -08004505 entry.pointerCoords[i] =
4506 MotionEvent::calculateTransformedCoords(entry.source, transformToDisplay,
4507 entry.pointerCoords[i]);
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004508 }
4509}
4510
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004511void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4512 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004513 if (injectionState) {
4514 injectionState->pendingForegroundDispatches += 1;
4515 }
4516}
4517
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004518void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4519 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004520 if (injectionState) {
4521 injectionState->pendingForegroundDispatches -= 1;
4522
4523 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004524 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004525 }
4526 }
4527}
4528
chaviw98318de2021-05-19 16:45:23 -05004529const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004530 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004531 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004532 auto it = mWindowHandlesByDisplay.find(displayId);
4533 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004534}
4535
chaviw98318de2021-05-19 16:45:23 -05004536sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004537 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004538 if (windowHandleToken == nullptr) {
4539 return nullptr;
4540 }
4541
Arthur Hungb92218b2018-08-14 12:00:21 +08004542 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004543 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4544 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004545 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004546 return windowHandle;
4547 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004548 }
4549 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004550 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004551}
4552
chaviw98318de2021-05-19 16:45:23 -05004553sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4554 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004555 if (windowHandleToken == nullptr) {
4556 return nullptr;
4557 }
4558
chaviw98318de2021-05-19 16:45:23 -05004559 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004560 if (windowHandle->getToken() == windowHandleToken) {
4561 return windowHandle;
4562 }
4563 }
4564 return nullptr;
4565}
4566
chaviw98318de2021-05-19 16:45:23 -05004567sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4568 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004569 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004570 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4571 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004572 if (handle->getId() == windowHandle->getId() &&
4573 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004574 if (windowHandle->getInfo()->displayId != it.first) {
4575 ALOGE("Found window %s in display %" PRId32
4576 ", but it should belong to display %" PRId32,
4577 windowHandle->getName().c_str(), it.first,
4578 windowHandle->getInfo()->displayId);
4579 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004580 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004581 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004582 }
4583 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004584 return nullptr;
4585}
4586
chaviw98318de2021-05-19 16:45:23 -05004587sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004588 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4589 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004590}
4591
chaviw98318de2021-05-19 16:45:23 -05004592bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004593 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4594 const bool noInputChannel =
Prabir Pradhan51e7db02022-02-07 06:02:57 -08004595 windowHandle.getInfo()->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004596 if (connection != nullptr && noInputChannel) {
4597 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4598 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4599 return false;
4600 }
4601
4602 if (connection == nullptr) {
4603 if (!noInputChannel) {
4604 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4605 }
4606 return false;
4607 }
4608 if (!connection->responsive) {
4609 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4610 return false;
4611 }
4612 return true;
4613}
4614
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004615std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4616 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004617 auto connectionIt = mConnectionsByToken.find(token);
4618 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004619 return nullptr;
4620 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004621 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004622}
4623
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004624void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004625 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4626 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004627 // Remove all handles on a display if there are no windows left.
4628 mWindowHandlesByDisplay.erase(displayId);
4629 return;
4630 }
4631
4632 // Since we compare the pointer of input window handles across window updates, we need
4633 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004634 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4635 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4636 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004637 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004638 }
4639
chaviw98318de2021-05-19 16:45:23 -05004640 std::vector<sp<WindowInfoHandle>> newHandles;
4641 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05004642 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004643 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004644 const bool noInputChannel =
Prabir Pradhan51e7db02022-02-07 06:02:57 -08004645 info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08004646 const bool canReceiveInput =
4647 !info->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) ||
4648 !info->inputConfig.test(WindowInfo::InputConfig::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004649 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004650 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004651 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004652 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004653 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004654 }
4655
4656 if (info->displayId != displayId) {
4657 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4658 handle->getName().c_str(), displayId, info->displayId);
4659 continue;
4660 }
4661
Robert Carredd13602020-04-13 17:24:34 -07004662 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4663 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004664 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004665 oldHandle->updateFrom(handle);
4666 newHandles.push_back(oldHandle);
4667 } else {
4668 newHandles.push_back(handle);
4669 }
4670 }
4671
4672 // Insert or replace
4673 mWindowHandlesByDisplay[displayId] = newHandles;
4674}
4675
Arthur Hung72d8dc32020-03-28 00:48:39 +00004676void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004677 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07004678 // TODO(b/198444055): Remove setInputWindows from InputDispatcher.
Arthur Hung72d8dc32020-03-28 00:48:39 +00004679 { // acquire lock
4680 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004681 for (const auto& [displayId, handles] : handlesPerDisplay) {
4682 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004683 }
4684 }
4685 // Wake up poll loop since it may need to make new input dispatching choices.
4686 mLooper->wake();
4687}
4688
Arthur Hungb92218b2018-08-14 12:00:21 +08004689/**
4690 * Called from InputManagerService, update window handle list by displayId that can receive input.
4691 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4692 * If set an empty list, remove all handles from the specific display.
4693 * For focused handle, check if need to change and send a cancel event to previous one.
4694 * For removed handle, check if need to send a cancel event if already in touch.
4695 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004696void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004697 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004698 if (DEBUG_FOCUS) {
4699 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004700 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004701 windowList += iwh->getName() + " ";
4702 }
4703 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4704 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004705
Prabir Pradhand65552b2021-10-07 11:23:50 -07004706 // Check preconditions for new input windows
chaviw98318de2021-05-19 16:45:23 -05004707 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07004708 const WindowInfo& info = *window->getInfo();
4709
4710 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
Prabir Pradhan51e7db02022-02-07 06:02:57 -08004711 const bool noInputWindow = info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004712 if (noInputWindow && window->getToken() != nullptr) {
4713 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4714 window->getName().c_str());
4715 window->releaseChannel();
4716 }
Prabir Pradhand65552b2021-10-07 11:23:50 -07004717
Prabir Pradhan5c85e052021-12-22 02:27:12 -08004718 // Ensure all spy windows are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08004719 LOG_ALWAYS_FATAL_IF(info.isSpy() &&
4720 !info.inputConfig.test(
4721 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhan5c85e052021-12-22 02:27:12 -08004722 "%s has feature SPY, but is not a trusted overlay.",
4723 window->getName().c_str());
4724
Prabir Pradhand65552b2021-10-07 11:23:50 -07004725 // Ensure all stylus interceptors are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08004726 LOG_ALWAYS_FATAL_IF(info.interceptsStylus() &&
4727 !info.inputConfig.test(
4728 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhand65552b2021-10-07 11:23:50 -07004729 "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
4730 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004731 }
4732
Arthur Hung72d8dc32020-03-28 00:48:39 +00004733 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004734 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004735
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004736 // Save the old windows' orientation by ID before it gets updated.
4737 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004738 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004739 oldWindowOrientations.emplace(handle->getId(),
4740 handle->getInfo()->transform.getOrientation());
4741 }
4742
chaviw98318de2021-05-19 16:45:23 -05004743 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004744
chaviw98318de2021-05-19 16:45:23 -05004745 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004746 if (mLastHoverWindowHandle &&
4747 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4748 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004749 mLastHoverWindowHandle = nullptr;
4750 }
4751
Vishnu Nairc519ff72021-01-21 08:23:08 -08004752 std::optional<FocusResolver::FocusChanges> changes =
4753 mFocusResolver.setInputWindows(displayId, windowHandles);
4754 if (changes) {
4755 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004756 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004757
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004758 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4759 mTouchStatesByDisplay.find(displayId);
4760 if (stateIt != mTouchStatesByDisplay.end()) {
4761 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004762 for (size_t i = 0; i < state.windows.size();) {
4763 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004764 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004765 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004766 ALOGD("Touched window was removed: %s in display %" PRId32,
4767 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004768 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004769 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004770 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4771 if (touchedInputChannel != nullptr) {
4772 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4773 "touched window was removed");
4774 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004775 // Since we are about to drop the touch, cancel the events for the wallpaper as
4776 // well.
4777 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND &&
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08004778 touchedWindow.windowHandle->getInfo()->inputConfig.test(
4779 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004780 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
4781 if (wallpaper != nullptr) {
4782 sp<Connection> wallpaperConnection =
4783 getConnectionLocked(wallpaper->getToken());
Siarhei Vishniakou2b030972021-11-18 10:01:27 -08004784 if (wallpaperConnection != nullptr) {
4785 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection,
4786 options);
4787 }
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004788 }
4789 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004790 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004791 state.windows.erase(state.windows.begin() + i);
4792 } else {
4793 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004794 }
4795 }
arthurhungb89ccb02020-12-30 16:19:01 +08004796
arthurhung6d4bed92021-03-17 11:59:33 +08004797 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004798 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004799 if (mDragState &&
4800 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004801 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004802 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004803 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004804 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004805
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00004806 // Determine if the orientation of any of the input windows have changed, and cancel all
4807 // pointer events if necessary.
4808 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4809 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
4810 if (newWindowHandle != nullptr &&
4811 newWindowHandle->getInfo()->transform.getOrientation() !=
4812 oldWindowOrientations[oldWindowHandle->getId()]) {
4813 std::shared_ptr<InputChannel> inputChannel =
4814 getInputChannelLocked(newWindowHandle->getToken());
4815 if (inputChannel != nullptr) {
4816 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4817 "touched window's orientation changed");
4818 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004819 }
4820 }
4821 }
4822
Arthur Hung72d8dc32020-03-28 00:48:39 +00004823 // Release information for windows that are no longer present.
4824 // This ensures that unused input channels are released promptly.
4825 // Otherwise, they might stick around until the window handle is destroyed
4826 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004827 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004828 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004829 if (DEBUG_FOCUS) {
4830 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004831 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004832 oldWindowHandle->releaseChannel();
Arthur Hung25e2af12020-03-26 12:58:37 +00004833 }
chaviw291d88a2019-02-14 10:33:58 -08004834 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004835}
4836
4837void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004838 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004839 if (DEBUG_FOCUS) {
4840 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4841 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4842 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004843 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004844 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004845 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004846 } // release lock
4847
4848 // Wake up poll loop since it may need to make new input dispatching choices.
4849 mLooper->wake();
4850}
4851
Vishnu Nair599f1412021-06-21 10:39:58 -07004852void InputDispatcher::setFocusedApplicationLocked(
4853 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4854 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4855 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4856
4857 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4858 return; // This application is already focused. No need to wake up or change anything.
4859 }
4860
4861 // Set the new application handle.
4862 if (inputApplicationHandle != nullptr) {
4863 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4864 } else {
4865 mFocusedApplicationHandlesByDisplay.erase(displayId);
4866 }
4867
4868 // No matter what the old focused application was, stop waiting on it because it is
4869 // no longer focused.
4870 resetNoFocusedWindowTimeoutLocked();
4871}
4872
Tiger Huang721e26f2018-07-24 22:26:19 +08004873/**
4874 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4875 * the display not specified.
4876 *
4877 * We track any unreleased events for each window. If a window loses the ability to receive the
4878 * released event, we will send a cancel event to it. So when the focused display is changed, we
4879 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4880 * display. The display-specified events won't be affected.
4881 */
4882void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004883 if (DEBUG_FOCUS) {
4884 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4885 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004886 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004887 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004888
4889 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004890 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004891 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004892 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004893 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004894 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004895 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004896 CancelationOptions
4897 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4898 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004899 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004900 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4901 }
4902 }
4903 mFocusedDisplayId = displayId;
4904
Chris Ye3c2d6f52020-08-09 10:39:48 -07004905 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004906 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004907 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004908
Vishnu Nairad321cd2020-08-20 16:40:21 -07004909 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004910 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004911 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004912 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004913 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004914 }
4915 }
4916 }
4917
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004918 if (DEBUG_FOCUS) {
4919 logDispatchStateLocked();
4920 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004921 } // release lock
4922
4923 // Wake up poll loop since it may need to make new input dispatching choices.
4924 mLooper->wake();
4925}
4926
Michael Wrightd02c5b62014-02-10 15:10:22 -08004927void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004928 if (DEBUG_FOCUS) {
4929 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4930 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004931
4932 bool changed;
4933 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004934 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004935
4936 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4937 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004938 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004939 }
4940
4941 if (mDispatchEnabled && !enabled) {
4942 resetAndDropEverythingLocked("dispatcher is being disabled");
4943 }
4944
4945 mDispatchEnabled = enabled;
4946 mDispatchFrozen = frozen;
4947 changed = true;
4948 } else {
4949 changed = false;
4950 }
4951
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004952 if (DEBUG_FOCUS) {
4953 logDispatchStateLocked();
4954 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004955 } // release lock
4956
4957 if (changed) {
4958 // Wake up poll loop since it may need to make new input dispatching choices.
4959 mLooper->wake();
4960 }
4961}
4962
4963void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004964 if (DEBUG_FOCUS) {
4965 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4966 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004967
4968 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004969 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004970
4971 if (mInputFilterEnabled == enabled) {
4972 return;
4973 }
4974
4975 mInputFilterEnabled = enabled;
4976 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4977 } // release lock
4978
4979 // Wake up poll loop since there might be work to do to drop everything.
4980 mLooper->wake();
4981}
4982
Antonio Kantekea47acb2021-12-23 12:41:25 -08004983bool InputDispatcher::setInTouchMode(bool inTouchMode, int32_t pid, int32_t uid,
4984 bool hasPermission) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00004985 bool needWake = false;
4986 {
4987 std::scoped_lock lock(mLock);
4988 if (mInTouchMode == inTouchMode) {
Antonio Kantekea47acb2021-12-23 12:41:25 -08004989 return false;
Antonio Kantekf16f2832021-09-28 04:39:20 +00004990 }
4991 if (DEBUG_TOUCH_MODE) {
Antonio Kantekea47acb2021-12-23 12:41:25 -08004992 ALOGD("Request to change touch mode from %s to %s (calling pid=%d, uid=%d, "
4993 "hasPermission=%s)",
4994 toString(mInTouchMode), toString(inTouchMode), pid, uid, toString(hasPermission));
4995 }
4996 if (!hasPermission) {
Antonio Kantek48710e42022-03-24 14:19:30 -07004997 if (!focusedWindowIsOwnedByLocked(pid, uid) &&
4998 !recentWindowsAreOwnedByLocked(pid, uid)) {
4999 ALOGD("Touch mode switch rejected, caller (pid=%d, uid=%d) doesn't own the focused "
5000 "window nor none of the previously interacted window",
5001 pid, uid);
Antonio Kantekea47acb2021-12-23 12:41:25 -08005002 return false;
5003 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00005004 }
5005
5006 // TODO(b/198499018): Store touch mode per display.
5007 mInTouchMode = inTouchMode;
5008
Antonio Kantekf16f2832021-09-28 04:39:20 +00005009 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode);
5010 needWake = enqueueInboundEventLocked(std::move(entry));
5011 } // release lock
5012
5013 if (needWake) {
5014 mLooper->wake();
5015 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005016 return true;
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08005017}
5018
Antonio Kantek48710e42022-03-24 14:19:30 -07005019bool InputDispatcher::focusedWindowIsOwnedByLocked(int32_t pid, int32_t uid) {
5020 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
5021 if (focusedToken == nullptr) {
5022 return false;
5023 }
5024 sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken);
5025 return isWindowOwnedBy(windowHandle, pid, uid);
5026}
5027
5028bool InputDispatcher::recentWindowsAreOwnedByLocked(int32_t pid, int32_t uid) {
5029 return std::find_if(mInteractionConnectionTokens.begin(), mInteractionConnectionTokens.end(),
5030 [&](const sp<IBinder>& connectionToken) REQUIRES(mLock) {
5031 const sp<WindowInfoHandle> windowHandle =
5032 getWindowHandleLocked(connectionToken);
5033 return isWindowOwnedBy(windowHandle, pid, uid);
5034 }) != mInteractionConnectionTokens.end();
5035}
5036
Bernardo Rufinoea97d182020-08-19 14:43:14 +01005037void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
5038 if (opacity < 0 || opacity > 1) {
5039 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
5040 return;
5041 }
5042
5043 std::scoped_lock lock(mLock);
5044 mMaximumObscuringOpacityForTouch = opacity;
5045}
5046
Arthur Hungabbb9d82021-09-01 14:52:30 +00005047std::pair<TouchState*, TouchedWindow*> InputDispatcher::findTouchStateAndWindowLocked(
5048 const sp<IBinder>& token) {
5049 for (auto& [displayId, state] : mTouchStatesByDisplay) {
5050 for (TouchedWindow& w : state.windows) {
5051 if (w.windowHandle->getToken() == token) {
5052 return std::make_pair(&state, &w);
5053 }
5054 }
5055 }
5056 return std::make_pair(nullptr, nullptr);
5057}
5058
arthurhungb89ccb02020-12-30 16:19:01 +08005059bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5060 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08005061 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005062 if (DEBUG_FOCUS) {
5063 ALOGD("Trivial transfer to same window.");
5064 }
chaviwfbe5d9c2018-12-26 12:23:37 -08005065 return true;
5066 }
5067
Michael Wrightd02c5b62014-02-10 15:10:22 -08005068 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005069 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005070
Arthur Hungabbb9d82021-09-01 14:52:30 +00005071 // Find the target touch state and touched window by fromToken.
5072 auto [state, touchedWindow] = findTouchStateAndWindowLocked(fromToken);
5073 if (state == nullptr || touchedWindow == nullptr) {
5074 ALOGD("Focus transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005075 return false;
5076 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00005077
5078 const int32_t displayId = state->displayId;
5079 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
5080 if (toWindowHandle == nullptr) {
5081 ALOGW("Cannot transfer focus because to window not found.");
5082 return false;
5083 }
5084
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005085 if (DEBUG_FOCUS) {
5086 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00005087 touchedWindow->windowHandle->getName().c_str(),
5088 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005089 }
5090
Arthur Hungabbb9d82021-09-01 14:52:30 +00005091 // Erase old window.
5092 int32_t oldTargetFlags = touchedWindow->targetFlags;
5093 BitSet32 pointerIds = touchedWindow->pointerIds;
5094 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005095
Arthur Hungabbb9d82021-09-01 14:52:30 +00005096 // Add new window.
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005097 int32_t newTargetFlags =
5098 oldTargetFlags & (InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
5099 if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) {
5100 newTargetFlags |= InputTarget::FLAG_FOREGROUND;
5101 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00005102 state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005103
Arthur Hungabbb9d82021-09-01 14:52:30 +00005104 // Store the dragging window.
5105 if (isDragDrop) {
5106 mDragState = std::make_unique<DragState>(toWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005107 }
5108
Arthur Hungabbb9d82021-09-01 14:52:30 +00005109 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005110 sp<Connection> fromConnection = getConnectionLocked(fromToken);
5111 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005112 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005113 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005114 CancelationOptions
5115 options(CancelationOptions::CANCEL_POINTER_EVENTS,
5116 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005117 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08005118 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005119 }
5120
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005121 if (DEBUG_FOCUS) {
5122 logDispatchStateLocked();
5123 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005124 } // release lock
5125
5126 // Wake up poll loop since it may need to make new input dispatching choices.
5127 mLooper->wake();
5128 return true;
5129}
5130
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005131/**
5132 * Get the touched foreground window on the given display.
5133 * Return null if there are no windows touched on that display, or if more than one foreground
5134 * window is being touched.
5135 */
5136sp<WindowInfoHandle> InputDispatcher::findTouchedForegroundWindowLocked(int32_t displayId) const {
5137 auto stateIt = mTouchStatesByDisplay.find(displayId);
5138 if (stateIt == mTouchStatesByDisplay.end()) {
5139 ALOGI("No touch state on display %" PRId32, displayId);
5140 return nullptr;
5141 }
5142
5143 const TouchState& state = stateIt->second;
5144 sp<WindowInfoHandle> touchedForegroundWindow;
5145 // If multiple foreground windows are touched, return nullptr
5146 for (const TouchedWindow& window : state.windows) {
5147 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5148 if (touchedForegroundWindow != nullptr) {
5149 ALOGI("Two or more foreground windows: %s and %s",
5150 touchedForegroundWindow->getName().c_str(),
5151 window.windowHandle->getName().c_str());
5152 return nullptr;
5153 }
5154 touchedForegroundWindow = window.windowHandle;
5155 }
5156 }
5157 return touchedForegroundWindow;
5158}
5159
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005160// Binder call
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005161bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken, int32_t displayId) {
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005162 sp<IBinder> fromToken;
5163 { // acquire lock
5164 std::scoped_lock _l(mLock);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005165 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005166 if (toWindowHandle == nullptr) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005167 ALOGW("Could not find window associated with token=%p on display %" PRId32,
5168 destChannelToken.get(), displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005169 return false;
5170 }
5171
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005172 sp<WindowInfoHandle> from = findTouchedForegroundWindowLocked(displayId);
5173 if (from == nullptr) {
5174 ALOGE("Could not find a source window in %s for %p", __func__, destChannelToken.get());
5175 return false;
5176 }
5177
5178 fromToken = from->getToken();
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005179 } // release lock
5180
5181 return transferTouchFocus(fromToken, destChannelToken);
5182}
5183
Michael Wrightd02c5b62014-02-10 15:10:22 -08005184void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005185 if (DEBUG_FOCUS) {
5186 ALOGD("Resetting and dropping all events (%s).", reason);
5187 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005188
5189 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
5190 synthesizeCancelationEventsForAllConnectionsLocked(options);
5191
5192 resetKeyRepeatLocked();
5193 releasePendingEventLocked();
5194 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005195 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005196
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005197 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005198 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005199 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07005200 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005201}
5202
5203void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005204 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005205 dumpDispatchStateLocked(dump);
5206
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005207 std::istringstream stream(dump);
5208 std::string line;
5209
5210 while (std::getline(stream, line, '\n')) {
5211 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005212 }
5213}
5214
Prabir Pradhan99987712020-11-10 18:43:05 -08005215std::string InputDispatcher::dumpPointerCaptureStateLocked() {
5216 std::string dump;
5217
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005218 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5219 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005220
5221 std::string windowName = "None";
5222 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005223 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005224 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5225 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5226 : "token has capture without window";
5227 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005228 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005229
5230 return dump;
5231}
5232
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005233void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005234 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5235 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5236 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005237 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005238
Tiger Huang721e26f2018-07-24 22:26:19 +08005239 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5240 dump += StringPrintf(INDENT "FocusedApplications:\n");
5241 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5242 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005243 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005244 const std::chrono::duration timeout =
5245 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005246 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005247 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005248 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005249 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005250 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005251 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005252 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005253
Vishnu Nairc519ff72021-01-21 08:23:08 -08005254 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005255 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005256
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005257 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005258 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005259 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
5260 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005261 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005262 state.displayId, toString(state.down), toString(state.split),
5263 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005264 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005265 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005266 for (size_t i = 0; i < state.windows.size(); i++) {
5267 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005268 dump += StringPrintf(INDENT4
5269 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
5270 i, touchedWindow.windowHandle->getName().c_str(),
5271 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005272 }
5273 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005274 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005275 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005276 }
5277 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005278 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005279 }
5280
arthurhung6d4bed92021-03-17 11:59:33 +08005281 if (mDragState) {
5282 dump += StringPrintf(INDENT "DragState:\n");
5283 mDragState->dump(dump, INDENT2);
5284 }
5285
Arthur Hungb92218b2018-08-14 12:00:21 +08005286 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005287 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5288 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5289 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5290 const auto& displayInfo = it->second;
5291 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5292 displayInfo.logicalHeight);
5293 displayInfo.transform.dump(dump, "transform", INDENT4);
5294 } else {
5295 dump += INDENT2 "No DisplayInfo found!\n";
5296 }
5297
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005298 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005299 dump += INDENT2 "Windows:\n";
5300 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005301 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5302 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005303
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005304 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005305 "inputConfig=%s, alpha=%.2f, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005306 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005307 "applicationInfo.name=%s, "
5308 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005309 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005310 i, windowInfo->name.c_str(), windowInfo->id,
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005311 windowInfo->displayId,
5312 windowInfo->inputConfig.string().c_str(),
5313 windowInfo->alpha, windowInfo->frameLeft,
5314 windowInfo->frameTop, windowInfo->frameRight,
5315 windowInfo->frameBottom, windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005316 windowInfo->applicationInfo.name.c_str(),
5317 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005318 dump += dumpRegion(windowInfo->touchableRegion);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005319 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005320 "ms, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005321 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005322 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005323 millis(windowInfo->dispatchingTimeout),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005324 toString(windowInfo->token != nullptr),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005325 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005326 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005327 }
5328 } else {
5329 dump += INDENT2 "Windows: <none>\n";
5330 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005331 }
5332 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005333 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005334 }
5335
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005336 if (!mGlobalMonitorsByDisplay.empty()) {
5337 for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
5338 dump += StringPrintf(INDENT "Global monitors on display %d:\n", displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00005339 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005340 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005341 } else {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005342 dump += INDENT "Global Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005343 }
5344
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005345 const nsecs_t currentTime = now();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005346
5347 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005348 if (!mRecentQueue.empty()) {
5349 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005350 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005351 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005352 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005353 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005354 }
5355 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005356 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005357 }
5358
5359 // Dump event currently being dispatched.
5360 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005361 dump += INDENT "PendingEvent:\n";
5362 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005363 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005364 dump += StringPrintf(", age=%" PRId64 "ms\n",
5365 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005366 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005367 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005368 }
5369
5370 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005371 if (!mInboundQueue.empty()) {
5372 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005373 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005374 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005375 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005376 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005377 }
5378 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005379 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005380 }
5381
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005382 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005383 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005384 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5385 const KeyReplacement& replacement = pair.first;
5386 int32_t newKeyCode = pair.second;
5387 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005388 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005389 }
5390 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005391 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005392 }
5393
Prabir Pradhancef936d2021-07-21 16:17:52 +00005394 if (!mCommandQueue.empty()) {
5395 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5396 } else {
5397 dump += INDENT "CommandQueue: <empty>\n";
5398 }
5399
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005400 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005401 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005402 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005403 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005404 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005405 connection->inputChannel->getFd().get(),
5406 connection->getInputChannelName().c_str(),
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005407 connection->getWindowName().c_str(),
5408 ftl::enum_string(connection->status).c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005409 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005410
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005411 if (!connection->outboundQueue.empty()) {
5412 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5413 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005414 dump += dumpQueue(connection->outboundQueue, currentTime);
5415
Michael Wrightd02c5b62014-02-10 15:10:22 -08005416 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005417 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005418 }
5419
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005420 if (!connection->waitQueue.empty()) {
5421 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5422 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005423 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005424 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005425 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005426 }
5427 }
5428 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005429 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005430 }
5431
5432 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005433 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5434 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005435 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005436 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005437 }
5438
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005439 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005440 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5441 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5442 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005443 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005444 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005445}
5446
Michael Wright3dd60e22019-03-27 22:06:44 +00005447void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5448 const size_t numMonitors = monitors.size();
5449 for (size_t i = 0; i < numMonitors; i++) {
5450 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005451 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005452 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5453 dump += "\n";
5454 }
5455}
5456
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005457class LooperEventCallback : public LooperCallback {
5458public:
5459 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5460 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5461
5462private:
5463 std::function<int(int events)> mCallback;
5464};
5465
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005466Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005467 if (DEBUG_CHANNEL_CREATION) {
5468 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5469 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005470
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005471 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005472 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005473 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005474
5475 if (result) {
5476 return base::Error(result) << "Failed to open input channel pair with name " << name;
5477 }
5478
Michael Wrightd02c5b62014-02-10 15:10:22 -08005479 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005480 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005481 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005482 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005483 sp<Connection> connection =
5484 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005485
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005486 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5487 ALOGE("Created a new connection, but the token %p is already known", token.get());
5488 }
5489 mConnectionsByToken.emplace(token, connection);
5490
5491 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5492 this, std::placeholders::_1, token);
5493
5494 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005495 } // release lock
5496
5497 // Wake the looper because some connections have changed.
5498 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005499 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005500}
5501
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005502Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005503 const std::string& name,
5504 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005505 std::shared_ptr<InputChannel> serverChannel;
5506 std::unique_ptr<InputChannel> clientChannel;
5507 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5508 if (result) {
5509 return base::Error(result) << "Failed to open input channel pair with name " << name;
5510 }
5511
Michael Wright3dd60e22019-03-27 22:06:44 +00005512 { // acquire lock
5513 std::scoped_lock _l(mLock);
5514
5515 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005516 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5517 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005518 }
5519
Garfield Tan15601662020-09-22 15:32:38 -07005520 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005521 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005522 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005523
5524 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5525 ALOGE("Created a new connection, but the token %p is already known", token.get());
5526 }
5527 mConnectionsByToken.emplace(token, connection);
5528 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5529 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005530
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005531 mGlobalMonitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005532
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005533 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wright3dd60e22019-03-27 22:06:44 +00005534 }
Garfield Tan15601662020-09-22 15:32:38 -07005535
Michael Wright3dd60e22019-03-27 22:06:44 +00005536 // Wake the looper because some connections have changed.
5537 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005538 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005539}
5540
Garfield Tan15601662020-09-22 15:32:38 -07005541status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005542 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005543 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005544
Garfield Tan15601662020-09-22 15:32:38 -07005545 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005546 if (status) {
5547 return status;
5548 }
5549 } // release lock
5550
5551 // Wake the poll loop because removing the connection may have changed the current
5552 // synchronization state.
5553 mLooper->wake();
5554 return OK;
5555}
5556
Garfield Tan15601662020-09-22 15:32:38 -07005557status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5558 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005559 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005560 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005561 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005562 return BAD_VALUE;
5563 }
5564
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005565 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005566
Michael Wrightd02c5b62014-02-10 15:10:22 -08005567 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005568 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005569 }
5570
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005571 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005572
5573 nsecs_t currentTime = now();
5574 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5575
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005576 connection->status = Connection::Status::ZOMBIE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005577 return OK;
5578}
5579
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005580void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005581 for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
5582 auto& [displayId, monitors] = *it;
5583 std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
5584 return monitor.inputChannel->getConnectionToken() == connectionToken;
5585 });
Michael Wright3dd60e22019-03-27 22:06:44 +00005586
Michael Wright3dd60e22019-03-27 22:06:44 +00005587 if (monitors.empty()) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005588 it = mGlobalMonitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005589 } else {
5590 ++it;
5591 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005592 }
5593}
5594
Michael Wright3dd60e22019-03-27 22:06:44 +00005595status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005596 std::scoped_lock _l(mLock);
Michael Wright3dd60e22019-03-27 22:06:44 +00005597
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005598 const std::shared_ptr<InputChannel> requestingChannel = getInputChannelLocked(token);
5599 if (!requestingChannel) {
5600 ALOGW("Attempted to pilfer pointers from an un-registered channel or invalid token");
5601 return BAD_VALUE;
Michael Wright3dd60e22019-03-27 22:06:44 +00005602 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005603
5604 auto [statePtr, windowPtr] = findTouchStateAndWindowLocked(token);
5605 if (statePtr == nullptr || windowPtr == nullptr || !statePtr->down) {
5606 ALOGW("Attempted to pilfer points from a channel without any on-going pointer streams."
5607 " Ignoring.");
5608 return BAD_VALUE;
5609 }
5610
5611 TouchState& state = *statePtr;
5612
5613 // Send cancel events to all the input channels we're stealing from.
5614 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
5615 "input channel stole pointer stream");
5616 options.deviceId = state.deviceId;
5617 options.displayId = state.displayId;
5618 std::string canceledWindows;
5619 for (const TouchedWindow& window : state.windows) {
5620 const std::shared_ptr<InputChannel> channel =
5621 getInputChannelLocked(window.windowHandle->getToken());
5622 if (channel != nullptr && channel->getConnectionToken() != token) {
5623 synthesizeCancelationEventsForInputChannelLocked(channel, options);
5624 canceledWindows += canceledWindows.empty() ? "[" : ", ";
5625 canceledWindows += channel->getName();
5626 }
5627 }
5628 canceledWindows += canceledWindows.empty() ? "[]" : "]";
5629 ALOGI("Channel %s is stealing touch from %s", requestingChannel->getName().c_str(),
5630 canceledWindows.c_str());
5631
Prabir Pradhane680f9b2022-02-04 04:24:00 -08005632 // Prevent the gesture from being sent to any other windows.
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005633 state.filterWindowsExcept(token);
Prabir Pradhane680f9b2022-02-04 04:24:00 -08005634 state.preventNewTargets = true;
Michael Wright3dd60e22019-03-27 22:06:44 +00005635 return OK;
5636}
5637
Prabir Pradhan99987712020-11-10 18:43:05 -08005638void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5639 { // acquire lock
5640 std::scoped_lock _l(mLock);
5641 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005642 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005643 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5644 windowHandle != nullptr ? windowHandle->getName().c_str()
5645 : "token without window");
5646 }
5647
Vishnu Nairc519ff72021-01-21 08:23:08 -08005648 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005649 if (focusedToken != windowToken) {
5650 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5651 enabled ? "enable" : "disable");
5652 return;
5653 }
5654
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005655 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08005656 ALOGW("Ignoring request to %s Pointer Capture: "
5657 "window has %s requested pointer capture.",
5658 enabled ? "enable" : "disable", enabled ? "already" : "not");
5659 return;
5660 }
5661
Christine Franksb768bb42021-11-29 12:11:31 -08005662 if (enabled) {
5663 if (std::find(mIneligibleDisplaysForPointerCapture.begin(),
5664 mIneligibleDisplaysForPointerCapture.end(),
5665 mFocusedDisplayId) != mIneligibleDisplaysForPointerCapture.end()) {
5666 ALOGW("Ignoring request to enable Pointer Capture: display is not eligible");
5667 return;
5668 }
5669 }
5670
Prabir Pradhan99987712020-11-10 18:43:05 -08005671 setPointerCaptureLocked(enabled);
5672 } // release lock
5673
5674 // Wake the thread to process command entries.
5675 mLooper->wake();
5676}
5677
Christine Franksb768bb42021-11-29 12:11:31 -08005678void InputDispatcher::setDisplayEligibilityForPointerCapture(int32_t displayId, bool isEligible) {
5679 { // acquire lock
5680 std::scoped_lock _l(mLock);
5681 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
5682 if (!isEligible) {
5683 mIneligibleDisplaysForPointerCapture.push_back(displayId);
5684 }
5685 } // release lock
5686}
5687
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005688std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5689 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005690 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005691 if (monitor.inputChannel->getConnectionToken() == token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005692 return monitor.pid;
Michael Wright3dd60e22019-03-27 22:06:44 +00005693 }
5694 }
5695 }
5696 return std::nullopt;
5697}
5698
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005699sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005700 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005701 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005702 }
5703
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005704 for (const auto& [token, connection] : mConnectionsByToken) {
5705 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005706 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005707 }
5708 }
Robert Carr4e670e52018-08-15 13:26:12 -07005709
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005710 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005711}
5712
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005713std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5714 sp<Connection> connection = getConnectionLocked(connectionToken);
5715 if (connection == nullptr) {
5716 return "<nullptr>";
5717 }
5718 return connection->getInputChannelName();
5719}
5720
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005721void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005722 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005723 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005724}
5725
Prabir Pradhancef936d2021-07-21 16:17:52 +00005726void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5727 const sp<Connection>& connection, uint32_t seq,
5728 bool handled, nsecs_t consumeTime) {
5729 // Handle post-event policy actions.
5730 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5731 if (dispatchEntryIt == connection->waitQueue.end()) {
5732 return;
5733 }
5734 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5735 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5736 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5737 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5738 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5739 }
5740 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5741 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5742 connection->inputChannel->getConnectionToken(),
5743 dispatchEntry->deliveryTime, consumeTime, finishTime);
5744 }
5745
5746 bool restartEvent;
5747 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5748 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5749 restartEvent =
5750 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5751 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5752 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5753 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5754 handled);
5755 } else {
5756 restartEvent = false;
5757 }
5758
5759 // Dequeue the event and start the next cycle.
5760 // Because the lock might have been released, it is possible that the
5761 // contents of the wait queue to have been drained, so we need to double-check
5762 // a few things.
5763 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5764 if (dispatchEntryIt != connection->waitQueue.end()) {
5765 dispatchEntry = *dispatchEntryIt;
5766 connection->waitQueue.erase(dispatchEntryIt);
5767 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5768 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5769 if (!connection->responsive) {
5770 connection->responsive = isConnectionResponsive(*connection);
5771 if (connection->responsive) {
5772 // The connection was unresponsive, and now it's responsive.
5773 processConnectionResponsiveLocked(*connection);
5774 }
5775 }
5776 traceWaitQueueLength(*connection);
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005777 if (restartEvent && connection->status == Connection::Status::NORMAL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005778 connection->outboundQueue.push_front(dispatchEntry);
5779 traceOutboundQueueLength(*connection);
5780 } else {
5781 releaseDispatchEntry(dispatchEntry);
5782 }
5783 }
5784
5785 // Start the next dispatch cycle for this connection.
5786 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005787}
5788
Prabir Pradhancef936d2021-07-21 16:17:52 +00005789void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5790 const sp<IBinder>& newToken) {
5791 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5792 scoped_unlock unlock(mLock);
5793 mPolicy->notifyFocusChanged(oldToken, newToken);
5794 };
5795 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005796}
5797
Prabir Pradhancef936d2021-07-21 16:17:52 +00005798void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5799 auto command = [this, token, x, y]() REQUIRES(mLock) {
5800 scoped_unlock unlock(mLock);
5801 mPolicy->notifyDropWindow(token, x, y);
5802 };
5803 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005804}
5805
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005806void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5807 if (connection == nullptr) {
5808 LOG_ALWAYS_FATAL("Caller must check for nullness");
5809 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005810 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5811 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005812 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005813 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005814 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005815 return;
5816 }
5817 /**
5818 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5819 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5820 * has changed. This could cause newer entries to time out before the already dispatched
5821 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5822 * processes the events linearly. So providing information about the oldest entry seems to be
5823 * most useful.
5824 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005825 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005826 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5827 std::string reason =
5828 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005829 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005830 ns2ms(currentWait),
5831 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005832 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005833 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005834
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005835 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5836
5837 // Stop waking up for events on this connection, it is already unresponsive
5838 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005839}
5840
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005841void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5842 std::string reason =
5843 StringPrintf("%s does not have a focused window", application->getName().c_str());
5844 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005845
Prabir Pradhancef936d2021-07-21 16:17:52 +00005846 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5847 scoped_unlock unlock(mLock);
5848 mPolicy->notifyNoFocusedWindowAnr(application);
5849 };
5850 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005851}
5852
chaviw98318de2021-05-19 16:45:23 -05005853void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005854 const std::string& reason) {
5855 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5856 updateLastAnrStateLocked(windowLabel, reason);
5857}
5858
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005859void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5860 const std::string& reason) {
5861 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005862 updateLastAnrStateLocked(windowLabel, reason);
5863}
5864
5865void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5866 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005867 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005868 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005869 struct tm tm;
5870 localtime_r(&t, &tm);
5871 char timestr[64];
5872 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005873 mLastAnrState.clear();
5874 mLastAnrState += INDENT "ANR:\n";
5875 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005876 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5877 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005878 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005879}
5880
Prabir Pradhancef936d2021-07-21 16:17:52 +00005881void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5882 KeyEntry& entry) {
5883 const KeyEvent event = createKeyEvent(entry);
5884 nsecs_t delay = 0;
5885 { // release lock
5886 scoped_unlock unlock(mLock);
5887 android::base::Timer t;
5888 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5889 entry.policyFlags);
5890 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5891 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5892 std::to_string(t.duration().count()).c_str());
5893 }
5894 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005895
5896 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005897 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005898 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005899 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005900 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005901 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5902 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005903 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005904}
5905
Prabir Pradhancef936d2021-07-21 16:17:52 +00005906void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhanedd96402022-02-15 01:46:16 -08005907 std::optional<int32_t> pid,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005908 std::string reason) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08005909 auto command = [this, token, pid, reason = std::move(reason)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005910 scoped_unlock unlock(mLock);
Prabir Pradhanedd96402022-02-15 01:46:16 -08005911 mPolicy->notifyWindowUnresponsive(token, pid, reason);
Prabir Pradhancef936d2021-07-21 16:17:52 +00005912 };
5913 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005914}
5915
Prabir Pradhanedd96402022-02-15 01:46:16 -08005916void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& token,
5917 std::optional<int32_t> pid) {
5918 auto command = [this, token, pid]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005919 scoped_unlock unlock(mLock);
Prabir Pradhanedd96402022-02-15 01:46:16 -08005920 mPolicy->notifyWindowResponsive(token, pid);
Prabir Pradhancef936d2021-07-21 16:17:52 +00005921 };
5922 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005923}
5924
5925/**
5926 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5927 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5928 * command entry to the command queue.
5929 */
5930void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5931 std::string reason) {
5932 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanedd96402022-02-15 01:46:16 -08005933 std::optional<int32_t> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005934 if (connection.monitor) {
5935 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5936 reason.c_str());
Prabir Pradhanedd96402022-02-15 01:46:16 -08005937 pid = findMonitorPidByTokenLocked(connectionToken);
5938 } else {
5939 // The connection is a window
5940 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5941 reason.c_str());
5942 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
5943 if (handle != nullptr) {
5944 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005945 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005946 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08005947 sendWindowUnresponsiveCommandLocked(connectionToken, pid, std::move(reason));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005948}
5949
5950/**
5951 * Tell the policy that a connection has become responsive so that it can stop ANR.
5952 */
5953void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5954 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanedd96402022-02-15 01:46:16 -08005955 std::optional<int32_t> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005956 if (connection.monitor) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08005957 pid = findMonitorPidByTokenLocked(connectionToken);
5958 } else {
5959 // The connection is a window
5960 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
5961 if (handle != nullptr) {
5962 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005963 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005964 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08005965 sendWindowResponsiveCommandLocked(connectionToken, pid);
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005966}
5967
Prabir Pradhancef936d2021-07-21 16:17:52 +00005968bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005969 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005970 KeyEntry& keyEntry, bool handled) {
5971 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005972 if (!handled) {
5973 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005974 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005975 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005976 return false;
5977 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005978
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005979 // Get the fallback key state.
5980 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005981 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005982 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005983 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005984 connection->inputState.removeFallbackKey(originalKeyCode);
5985 }
5986
5987 if (handled || !dispatchEntry->hasForegroundTarget()) {
5988 // If the application handles the original key for which we previously
5989 // generated a fallback or if the window is not a foreground window,
5990 // then cancel the associated fallback key, if any.
5991 if (fallbackKeyCode != -1) {
5992 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005993 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5994 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
5995 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5996 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
5997 keyEntry.policyFlags);
5998 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005999 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006000 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006001
6002 mLock.unlock();
6003
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006004 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006005 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006006
6007 mLock.lock();
6008
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006009 // Cancel the fallback key.
6010 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006011 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006012 "application handled the original non-fallback key "
6013 "or is no longer a foreground target, "
6014 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08006015 options.keyCode = fallbackKeyCode;
6016 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006017 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006018 connection->inputState.removeFallbackKey(originalKeyCode);
6019 }
6020 } else {
6021 // If the application did not handle a non-fallback key, first check
6022 // that we are in a good state to perform unhandled key event processing
6023 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006024 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006025 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006026 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6027 ALOGD("Unhandled key event: Skipping unhandled key event processing "
6028 "since this is not an initial down. "
6029 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6030 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6031 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006032 return false;
6033 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006034
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006035 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006036 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6037 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
6038 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6039 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6040 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006041 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006042
6043 mLock.unlock();
6044
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006045 bool fallback =
6046 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006047 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006048
6049 mLock.lock();
6050
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08006051 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006052 connection->inputState.removeFallbackKey(originalKeyCode);
6053 return false;
6054 }
6055
6056 // Latch the fallback keycode for this key on an initial down.
6057 // The fallback keycode cannot change at any other point in the lifecycle.
6058 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006059 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006060 fallbackKeyCode = event.getKeyCode();
6061 } else {
6062 fallbackKeyCode = AKEYCODE_UNKNOWN;
6063 }
6064 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
6065 }
6066
6067 ALOG_ASSERT(fallbackKeyCode != -1);
6068
6069 // Cancel the fallback key if the policy decides not to send it anymore.
6070 // We will continue to dispatch the key to the policy but we will no
6071 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006072 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
6073 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006074 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6075 if (fallback) {
6076 ALOGD("Unhandled key event: Policy requested to send key %d"
6077 "as a fallback for %d, but on the DOWN it had requested "
6078 "to send %d instead. Fallback canceled.",
6079 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
6080 } else {
6081 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6082 "but on the DOWN it had requested to send %d. "
6083 "Fallback canceled.",
6084 originalKeyCode, fallbackKeyCode);
6085 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006086 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006087
6088 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
6089 "canceling fallback, policy no longer desires it");
6090 options.keyCode = fallbackKeyCode;
6091 synthesizeCancelationEventsForConnectionLocked(connection, options);
6092
6093 fallback = false;
6094 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006095 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006096 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006097 }
6098 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006099
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006100 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6101 {
6102 std::string msg;
6103 const KeyedVector<int32_t, int32_t>& fallbackKeys =
6104 connection->inputState.getFallbackKeys();
6105 for (size_t i = 0; i < fallbackKeys.size(); i++) {
6106 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
6107 }
6108 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6109 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006110 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006111 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006112
6113 if (fallback) {
6114 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006115 keyEntry.eventTime = event.getEventTime();
6116 keyEntry.deviceId = event.getDeviceId();
6117 keyEntry.source = event.getSource();
6118 keyEntry.displayId = event.getDisplayId();
6119 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
6120 keyEntry.keyCode = fallbackKeyCode;
6121 keyEntry.scanCode = event.getScanCode();
6122 keyEntry.metaState = event.getMetaState();
6123 keyEntry.repeatCount = event.getRepeatCount();
6124 keyEntry.downTime = event.getDownTime();
6125 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006126
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006127 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6128 ALOGD("Unhandled key event: Dispatching fallback key. "
6129 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
6130 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
6131 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006132 return true; // restart the event
6133 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006134 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6135 ALOGD("Unhandled key event: No fallback key.");
6136 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006137
6138 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006139 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006140 }
6141 }
6142 return false;
6143}
6144
Prabir Pradhancef936d2021-07-21 16:17:52 +00006145bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006146 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006147 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006148 return false;
6149}
6150
Michael Wrightd02c5b62014-02-10 15:10:22 -08006151void InputDispatcher::traceInboundQueueLengthLocked() {
6152 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006153 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006154 }
6155}
6156
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006157void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006158 if (ATRACE_ENABLED()) {
6159 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006160 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6161 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006162 }
6163}
6164
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006165void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006166 if (ATRACE_ENABLED()) {
6167 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006168 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6169 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006170 }
6171}
6172
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006173void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006174 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006175
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006176 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006177 dumpDispatchStateLocked(dump);
6178
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006179 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006180 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006181 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006182 }
6183}
6184
6185void InputDispatcher::monitor() {
6186 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006187 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006188 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006189 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006190}
6191
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006192/**
6193 * Wake up the dispatcher and wait until it processes all events and commands.
6194 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6195 * this method can be safely called from any thread, as long as you've ensured that
6196 * the work you are interested in completing has already been queued.
6197 */
6198bool InputDispatcher::waitForIdle() {
6199 /**
6200 * Timeout should represent the longest possible time that a device might spend processing
6201 * events and commands.
6202 */
6203 constexpr std::chrono::duration TIMEOUT = 100ms;
6204 std::unique_lock lock(mLock);
6205 mLooper->wake();
6206 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6207 return result == std::cv_status::no_timeout;
6208}
6209
Vishnu Naire798b472020-07-23 13:52:21 -07006210/**
6211 * Sets focus to the window identified by the token. This must be called
6212 * after updating any input window handles.
6213 *
6214 * Params:
6215 * request.token - input channel token used to identify the window that should gain focus.
6216 * request.focusedToken - the token that the caller expects currently to be focused. If the
6217 * specified token does not match the currently focused window, this request will be dropped.
6218 * If the specified focused token matches the currently focused window, the call will succeed.
6219 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6220 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6221 * when requesting the focus change. This determines which request gets
6222 * precedence if there is a focus change request from another source such as pointer down.
6223 */
Vishnu Nair958da932020-08-21 17:12:37 -07006224void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6225 { // acquire lock
6226 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006227 std::optional<FocusResolver::FocusChanges> changes =
6228 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6229 if (changes) {
6230 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006231 }
6232 } // release lock
6233 // Wake up poll loop since it may need to make new input dispatching choices.
6234 mLooper->wake();
6235}
6236
Vishnu Nairc519ff72021-01-21 08:23:08 -08006237void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6238 if (changes.oldFocus) {
6239 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006240 if (focusedInputChannel) {
6241 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6242 "focus left window");
6243 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006244 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006245 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006246 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006247 if (changes.newFocus) {
6248 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006249 }
6250
Prabir Pradhan99987712020-11-10 18:43:05 -08006251 // If a window has pointer capture, then it must have focus. We need to ensure that this
6252 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6253 // If the window loses focus before it loses pointer capture, then the window can be in a state
6254 // where it has pointer capture but not focus, violating the contract. Therefore we must
6255 // dispatch the pointer capture event before the focus event. Since focus events are added to
6256 // the front of the queue (above), we add the pointer capture event to the front of the queue
6257 // after the focus events are added. This ensures the pointer capture event ends up at the
6258 // front.
6259 disablePointerCaptureForcedLocked();
6260
Vishnu Nairc519ff72021-01-21 08:23:08 -08006261 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006262 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006263 }
6264}
Vishnu Nair958da932020-08-21 17:12:37 -07006265
Prabir Pradhan99987712020-11-10 18:43:05 -08006266void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006267 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006268 return;
6269 }
6270
6271 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6272
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006273 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006274 setPointerCaptureLocked(false);
6275 }
6276
6277 if (!mWindowTokenWithPointerCapture) {
6278 // No need to send capture changes because no window has capture.
6279 return;
6280 }
6281
6282 if (mPendingEvent != nullptr) {
6283 // Move the pending event to the front of the queue. This will give the chance
6284 // for the pending event to be dropped if it is a captured event.
6285 mInboundQueue.push_front(mPendingEvent);
6286 mPendingEvent = nullptr;
6287 }
6288
6289 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006290 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006291 mInboundQueue.push_front(std::move(entry));
6292}
6293
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006294void InputDispatcher::setPointerCaptureLocked(bool enable) {
6295 mCurrentPointerCaptureRequest.enable = enable;
6296 mCurrentPointerCaptureRequest.seq++;
6297 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006298 scoped_unlock unlock(mLock);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006299 mPolicy->setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006300 };
6301 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006302}
6303
Vishnu Nair599f1412021-06-21 10:39:58 -07006304void InputDispatcher::displayRemoved(int32_t displayId) {
6305 { // acquire lock
6306 std::scoped_lock _l(mLock);
6307 // Set an empty list to remove all handles from the specific display.
6308 setInputWindowsLocked(/* window handles */ {}, displayId);
6309 setFocusedApplicationLocked(displayId, nullptr);
6310 // Call focus resolver to clean up stale requests. This must be called after input windows
6311 // have been removed for the removed display.
6312 mFocusResolver.displayRemoved(displayId);
Christine Franksb768bb42021-11-29 12:11:31 -08006313 // Reset pointer capture eligibility, regardless of previous state.
6314 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006315 } // release lock
6316
6317 // Wake up poll loop since it may need to make new input dispatching choices.
6318 mLooper->wake();
6319}
6320
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006321void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
6322 const std::vector<DisplayInfo>& displayInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006323 // The listener sends the windows as a flattened array. Separate the windows by display for
6324 // more convenient parsing.
6325 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
chaviw15fab6f2021-06-07 14:15:52 -05006326 for (const auto& info : windowInfos) {
6327 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
6328 handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
6329 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006330
6331 { // acquire lock
6332 std::scoped_lock _l(mLock);
6333 mDisplayInfos.clear();
6334 for (const auto& displayInfo : displayInfos) {
6335 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6336 }
6337
6338 for (const auto& [displayId, handles] : handlesPerDisplay) {
6339 setInputWindowsLocked(handles, displayId);
6340 }
6341 }
6342 // Wake up poll loop since it may need to make new input dispatching choices.
6343 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006344}
6345
Vishnu Nair062a8672021-09-03 16:07:44 -07006346bool InputDispatcher::shouldDropInput(
6347 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006348 if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
6349 (windowHandle->getInfo()->inputConfig.test(
6350 WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
Vishnu Nair062a8672021-09-03 16:07:44 -07006351 isWindowObscuredLocked(windowHandle))) {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006352 ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on "
6353 "display %" PRId32 ".",
Vishnu Nair062a8672021-09-03 16:07:44 -07006354 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006355 windowHandle->getInfo()->inputConfig.string().c_str(),
Vishnu Nair062a8672021-09-03 16:07:44 -07006356 windowHandle->getInfo()->displayId);
6357 return true;
6358 }
6359 return false;
6360}
6361
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006362void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
6363 const std::vector<gui::WindowInfo>& windowInfos,
6364 const std::vector<DisplayInfo>& displayInfos) {
6365 mDispatcher.onWindowInfosChanged(windowInfos, displayInfos);
6366}
6367
Arthur Hungdfd528e2021-12-08 13:23:04 +00006368void InputDispatcher::cancelCurrentTouch() {
6369 {
6370 std::scoped_lock _l(mLock);
6371 ALOGD("Canceling all ongoing pointer gestures on all displays.");
6372 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
6373 "cancel current touch");
6374 synthesizeCancelationEventsForAllConnectionsLocked(options);
6375
6376 mTouchStatesByDisplay.clear();
6377 mLastHoverWindowHandle.clear();
6378 }
6379 // Wake up poll loop since there might be work to do.
6380 mLooper->wake();
6381}
6382
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08006383void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout) {
6384 std::scoped_lock _l(mLock);
6385 mMonitorDispatchingTimeout = timeout;
6386}
6387
Garfield Tane84e6f92019-08-29 17:28:41 -07006388} // namespace android::inputdispatcher