blob: 8d0ff4ba20946519c42cb38bb0c8f0fde30a6d77 [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>
Siarhei Vishniakoud010b012023-01-18 15:00:53 -080023#include <android-base/logging.h>
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080024#include <android-base/properties.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080025#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050026#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070027#include <binder/Binder.h>
Ameer Armalycff4fa52023-10-04 23:45:11 +000028#include <com_android_input_flags.h>
Dominik Laskowski75788452021-02-09 18:51:25 -080029#include <ftl/enum.h>
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -070030#include <log/log_event_list.h>
Siarhei Vishniakou31977182022-09-30 08:51:23 -070031#if defined(__ANDROID__)
chaviw15fab6f2021-06-07 14:15:52 -050032#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou31977182022-09-30 08:51:23 -070033#endif
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080034#include <input/InputDevice.h>
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -080035#include <input/PrintTools.h>
Prabir Pradhana37bad12023-08-18 15:55:32 +000036#include <input/TraceTools.h>
tyiu1573a672023-02-21 22:38:32 +000037#include <openssl/mem.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070038#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010039#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070040#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080041
Michael Wright44753b12020-07-08 13:48:11 +010042#include <cerrno>
43#include <cinttypes>
44#include <climits>
45#include <cstddef>
46#include <ctime>
47#include <queue>
48#include <sstream>
49
Asmita Poddardd9a6cd2023-09-26 15:35:12 +000050#include "../InputDeviceMetricsSource.h"
51
Michael Wright44753b12020-07-08 13:48:11 +010052#include "Connection.h"
Arthur Hung1a1007b2022-05-11 07:15:01 +000053#include "DebugConfig.h"
Chris Yef59a2f42020-10-16 12:55:26 -070054#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010055
Michael Wrightd02c5b62014-02-10 15:10:22 -080056#define INDENT " "
57#define INDENT2 " "
58#define INDENT3 " "
59#define INDENT4 " "
60
Siarhei Vishniakou253f4642022-11-09 13:42:06 -080061using namespace android::ftl::flag_operators;
Siarhei Vishniakou23740b92023-04-21 11:30:20 -070062using android::base::Error;
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080063using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000064using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080065using android::base::StringPrintf;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -070066using android::gui::DisplayInfo;
chaviw98318de2021-05-19 16:45:23 -050067using android::gui::FocusRequest;
68using android::gui::TouchOcclusionMode;
69using android::gui::WindowInfo;
70using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080071using android::os::InputEventInjectionResult;
72using android::os::InputEventInjectionSync;
Ameer Armalycff4fa52023-10-04 23:45:11 +000073namespace input_flags = com::android::input::flags;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080074
Siarhei Vishniakou18a1d512023-12-15 13:47:33 -080075// TODO(b/312714754): remove the corresponding code, as well.
76static const bool REMOVE_APP_SWITCH_DROPS = true;
Siarhei Vishniakou17f12282023-11-02 13:40:29 -070077
Garfield Tane84e6f92019-08-29 17:28:41 -070078namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080079
Prabir Pradhancef936d2021-07-21 16:17:52 +000080namespace {
Prabir Pradhancef936d2021-07-21 16:17:52 +000081// Temporarily releases a held mutex for the lifetime of the instance.
82// Named to match std::scoped_lock
83class scoped_unlock {
84public:
85 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
86 ~scoped_unlock() { mMutex.lock(); }
87
88private:
89 std::mutex& mMutex;
90};
91
Michael Wrightd02c5b62014-02-10 15:10:22 -080092// Default input dispatching timeout if there is no focused application or paused window
93// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080094const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
95 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
96 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -080097
98// Amount of time to allow for all pending events to be processed when an app switch
99// key is on the way. This is used to preempt input dispatch and drop input events
100// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000101constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800102
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800103const std::chrono::duration STALE_EVENT_TIMEOUT = std::chrono::seconds(10) * HwTimeoutMultiplier();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104
Michael Wrightd02c5b62014-02-10 15:10:22 -0800105// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +0000106constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
107
108// Log a warning when an interception call takes longer than this to process.
109constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800110
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700111// Additional key latency in case a connection is still processing some motion events.
112// This will help with the case when a user touched a button that opens a new window,
113// and gives us the chance to dispatch the key to this new window.
114constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
115
Michael Wrightd02c5b62014-02-10 15:10:22 -0800116// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000117constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
118
Antonio Kantekea47acb2021-12-23 12:41:25 -0800119// Event log tags. See EventLogTags.logtags for reference.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000120constexpr int LOGTAG_INPUT_INTERACTION = 62000;
121constexpr int LOGTAG_INPUT_FOCUS = 62001;
Arthur Hungb3307ee2021-10-14 10:57:37 +0000122constexpr int LOGTAG_INPUT_CANCEL = 62003;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000123
Prabir Pradhan33e3baa2022-12-06 20:30:22 +0000124const ui::Transform kIdentityTransform;
125
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000126inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800127 return systemTime(SYSTEM_TIME_MONOTONIC);
128}
129
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700130inline const std::string binderToString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000131 if (binder == nullptr) {
132 return "<null>";
133 }
134 return StringPrintf("%p", binder.get());
135}
136
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000137static std::string uidString(const gui::Uid& uid) {
138 return uid.toString();
139}
140
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700141Result<void> checkKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800142 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700143 case AKEY_EVENT_ACTION_DOWN:
144 case AKEY_EVENT_ACTION_UP:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700145 return {};
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700146 default:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700147 return Error() << "Key event has invalid action code " << action;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800148 }
149}
150
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700151Result<void> validateKeyEvent(int32_t action) {
152 return checkKeyAction(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800153}
154
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700155Result<void> checkMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800156 switch (MotionEvent::getActionMasked(action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700157 case AMOTION_EVENT_ACTION_DOWN:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700158 case AMOTION_EVENT_ACTION_UP: {
159 if (pointerCount != 1) {
160 return Error() << "invalid pointer count " << pointerCount;
161 }
162 return {};
163 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700164 case AMOTION_EVENT_ACTION_MOVE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700165 case AMOTION_EVENT_ACTION_HOVER_ENTER:
166 case AMOTION_EVENT_ACTION_HOVER_MOVE:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700167 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
168 if (pointerCount < 1) {
169 return Error() << "invalid pointer count " << pointerCount;
170 }
171 return {};
172 }
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800173 case AMOTION_EVENT_ACTION_CANCEL:
174 case AMOTION_EVENT_ACTION_OUTSIDE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700175 case AMOTION_EVENT_ACTION_SCROLL:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700176 return {};
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700177 case AMOTION_EVENT_ACTION_POINTER_DOWN:
178 case AMOTION_EVENT_ACTION_POINTER_UP: {
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800179 const int32_t index = MotionEvent::getActionIndex(action);
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700180 if (index < 0) {
181 return Error() << "invalid index " << index << " for "
182 << MotionEvent::actionToString(action);
183 }
184 if (index >= pointerCount) {
185 return Error() << "invalid index " << index << " for pointerCount " << pointerCount;
186 }
187 if (pointerCount <= 1) {
188 return Error() << "invalid pointer count " << pointerCount << " for "
189 << MotionEvent::actionToString(action);
190 }
191 return {};
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700192 }
193 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700194 case AMOTION_EVENT_ACTION_BUTTON_RELEASE: {
195 if (actionButton == 0) {
196 return Error() << "action button should be nonzero for "
197 << MotionEvent::actionToString(action);
198 }
199 return {};
200 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700201 default:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700202 return Error() << "invalid action " << action;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800203 }
204}
205
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000206int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500207 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
208}
209
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700210Result<void> validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
211 const PointerProperties* pointerProperties) {
212 Result<void> actionCheck = checkMotionAction(action, actionButton, pointerCount);
213 if (!actionCheck.ok()) {
214 return actionCheck;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800215 }
216 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700217 return Error() << "Motion event has invalid pointer count " << pointerCount
218 << "; value must be between 1 and " << MAX_POINTERS << ".";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800219 }
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800220 std::bitset<MAX_POINTER_ID + 1> pointerIdBits;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800221 for (size_t i = 0; i < pointerCount; i++) {
222 int32_t id = pointerProperties[i].id;
223 if (id < 0 || id > MAX_POINTER_ID) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700224 return Error() << "Motion event has invalid pointer id " << id
225 << "; value must be between 0 and " << MAX_POINTER_ID;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800226 }
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800227 if (pointerIdBits.test(id)) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700228 return Error() << "Motion event has duplicate pointer id " << id;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800229 }
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800230 pointerIdBits.set(id);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800231 }
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700232 return {};
233}
234
235Result<void> validateInputEvent(const InputEvent& event) {
236 switch (event.getType()) {
237 case InputEventType::KEY: {
238 const KeyEvent& key = static_cast<const KeyEvent&>(event);
239 const int32_t action = key.getAction();
240 return validateKeyEvent(action);
241 }
242 case InputEventType::MOTION: {
243 const MotionEvent& motion = static_cast<const MotionEvent&>(event);
244 const int32_t action = motion.getAction();
245 const size_t pointerCount = motion.getPointerCount();
246 const PointerProperties* pointerProperties = motion.getPointerProperties();
247 const int32_t actionButton = motion.getActionButton();
248 return validateMotionEvent(action, actionButton, pointerCount, pointerProperties);
249 }
250 default: {
251 return {};
252 }
253 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800254}
255
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -0800256std::bitset<MAX_POINTER_ID + 1> getPointerIds(const std::vector<PointerProperties>& pointers) {
257 std::bitset<MAX_POINTER_ID + 1> pointerIds;
258 for (const PointerProperties& pointer : pointers) {
259 pointerIds.set(pointer.id);
260 }
261 return pointerIds;
262}
263
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000264std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800265 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000266 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800267 }
268
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000269 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800270 bool first = true;
271 Region::const_iterator cur = region.begin();
272 Region::const_iterator const tail = region.end();
273 while (cur != tail) {
274 if (first) {
275 first = false;
276 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800277 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800278 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800279 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800280 cur++;
281 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000282 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800283}
284
Prabir Pradhan8c90d782023-09-15 21:16:44 +0000285std::string dumpQueue(const std::deque<std::unique_ptr<DispatchEntry>>& queue,
286 nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500287 constexpr size_t maxEntries = 50; // max events to print
288 constexpr size_t skipBegin = maxEntries / 2;
289 const size_t skipEnd = queue.size() - maxEntries / 2;
290 // skip from maxEntries / 2 ... size() - maxEntries/2
291 // only print from 0 .. skipBegin and then from skipEnd .. size()
292
293 std::string dump;
294 for (size_t i = 0; i < queue.size(); i++) {
295 const DispatchEntry& entry = *queue[i];
296 if (i >= skipBegin && i < skipEnd) {
297 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
298 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
299 continue;
300 }
301 dump.append(INDENT4);
302 dump += entry.eventEntry->getDescription();
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +0000303 dump += StringPrintf(", seq=%" PRIu32 ", targetFlags=%s, age=%" PRId64 "ms", entry.seq,
304 entry.targetFlags.string().c_str(),
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500305 ns2ms(currentTime - entry.eventEntry->eventTime));
306 if (entry.deliveryTime != 0) {
307 // This entry was delivered, so add information on how long we've been waiting
308 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
309 }
310 dump.append("\n");
311 }
312 return dump;
313}
314
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700315/**
316 * Find the entry in std::unordered_map by key, and return it.
317 * If the entry is not found, return a default constructed entry.
318 *
319 * Useful when the entries are vectors, since an empty vector will be returned
320 * if the entry is not found.
321 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
322 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700323template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000324V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700325 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700326 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800327}
328
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000329bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700330 if (first == second) {
331 return true;
332 }
333
334 if (first == nullptr || second == nullptr) {
335 return false;
336 }
337
338 return first->getToken() == second->getToken();
339}
340
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000341bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000342 if (first == nullptr || second == nullptr) {
343 return false;
344 }
345 return first->applicationInfo.token != nullptr &&
346 first->applicationInfo.token == second->applicationInfo.token;
347}
348
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800349template <typename T>
350size_t firstMarkedBit(T set) {
351 // TODO: replace with std::countr_zero from <bit> when that's available
352 LOG_ALWAYS_FATAL_IF(set.none());
353 size_t i = 0;
354 while (!set.test(i)) {
355 i++;
356 }
357 return i;
358}
359
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800360std::unique_ptr<DispatchEntry> createDispatchEntry(
Prabir Pradhan24047542023-11-02 17:14:59 +0000361 const InputTarget& inputTarget, std::shared_ptr<const EventEntry> eventEntry,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800362 ftl::Flags<InputTarget::Flags> inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700363 if (inputTarget.useDefaultPointerTransform()) {
364 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700365 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700366 inputTarget.displayTransform,
367 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000368 }
369
370 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
371 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
372
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700373 std::vector<PointerCoords> pointerCoords;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700374 pointerCoords.resize(motionEntry.getPointerCount());
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000375
376 // Use the first pointer information to normalize all other pointers. This could be any pointer
377 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700378 // uses the transform for the normalized pointer.
379 const ui::Transform& firstPointerTransform =
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800380 inputTarget.pointerTransforms[firstMarkedBit(inputTarget.pointerIds)];
chaviw1ff3d1e2020-07-01 15:53:47 -0700381 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000382
383 // Iterate through all pointers in the event to normalize against the first.
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700384 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount(); pointerIndex++) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000385 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
386 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700387 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000388
389 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700390 // First, apply the current pointer's transform to update the coordinates into
391 // window space.
392 pointerCoords[pointerIndex].transform(currTransform);
393 // Next, apply the inverse transform of the normalized coordinates so the
394 // current coordinates are transformed into the normalized coordinate space.
395 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000396 }
397
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700398 std::unique_ptr<MotionEntry> combinedMotionEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +0000399 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.injectionState,
400 motionEntry.eventTime, motionEntry.deviceId,
401 motionEntry.source, motionEntry.displayId,
402 motionEntry.policyFlags, motionEntry.action,
403 motionEntry.actionButton, motionEntry.flags,
404 motionEntry.metaState, motionEntry.buttonState,
405 motionEntry.classification, motionEntry.edgeFlags,
406 motionEntry.xPrecision, motionEntry.yPrecision,
407 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
408 motionEntry.downTime, motionEntry.pointerProperties,
409 pointerCoords);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000410
411 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700412 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700413 firstPointerTransform, inputTarget.displayTransform,
414 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000415 return dispatchEntry;
416}
417
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000418status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
419 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700420 std::unique_ptr<InputChannel> uniqueServerChannel;
421 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
422
423 serverChannel = std::move(uniqueServerChannel);
424 return result;
425}
426
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500427template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000428bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500429 if (lhs == nullptr && rhs == nullptr) {
430 return true;
431 }
432 if (lhs == nullptr || rhs == nullptr) {
433 return false;
434 }
435 return *lhs == *rhs;
436}
437
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000438KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000439 KeyEvent event;
440 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
441 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
442 entry.repeatCount, entry.downTime, entry.eventTime);
443 return event;
444}
445
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000446bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000447 // Do not keep track of gesture monitors. They receive every event and would disproportionately
448 // affect the statistics.
449 if (connection.monitor) {
450 return false;
451 }
452 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
453 if (!connection.responsive) {
454 return false;
455 }
456 return true;
457}
458
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000459bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000460 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
461 const int32_t& inputEventId = eventEntry.id;
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000462 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
463 return false;
464 }
465 // Only track latency for events that originated from hardware
466 if (eventEntry.isSynthesized()) {
467 return false;
468 }
469 const EventEntry::Type& inputEventEntryType = eventEntry.type;
470 if (inputEventEntryType == EventEntry::Type::KEY) {
471 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
472 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
473 return false;
474 }
475 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
476 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
477 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
478 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
479 return false;
480 }
481 } else {
482 // Not a key or a motion
483 return false;
484 }
485 if (!shouldReportMetricsForConnection(connection)) {
486 return false;
487 }
488 return true;
489}
490
Prabir Pradhancef936d2021-07-21 16:17:52 +0000491/**
492 * Connection is responsive if it has no events in the waitQueue that are older than the
493 * current time.
494 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000495bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000496 const nsecs_t currentTime = now();
Prabir Pradhan8c90d782023-09-15 21:16:44 +0000497 for (const auto& dispatchEntry : connection.waitQueue) {
498 if (dispatchEntry->timeoutTime < currentTime) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000499 return false;
500 }
501 }
502 return true;
503}
504
Antonio Kantekf16f2832021-09-28 04:39:20 +0000505// Returns true if the event type passed as argument represents a user activity.
506bool isUserActivityEvent(const EventEntry& eventEntry) {
507 switch (eventEntry.type) {
Josep del Riob3981622023-04-18 15:49:45 +0000508 case EventEntry::Type::CONFIGURATION_CHANGED:
509 case EventEntry::Type::DEVICE_RESET:
510 case EventEntry::Type::DRAG:
Antonio Kantekf16f2832021-09-28 04:39:20 +0000511 case EventEntry::Type::FOCUS:
512 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Antonio Kantekf16f2832021-09-28 04:39:20 +0000513 case EventEntry::Type::SENSOR:
Josep del Riob3981622023-04-18 15:49:45 +0000514 case EventEntry::Type::TOUCH_MODE_CHANGED:
Antonio Kantekf16f2832021-09-28 04:39:20 +0000515 return false;
Antonio Kantekf16f2832021-09-28 04:39:20 +0000516 case EventEntry::Type::KEY:
517 case EventEntry::Type::MOTION:
518 return true;
519 }
520}
521
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800522// Returns true if the given window can accept pointer events at the given display location.
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000523bool windowAcceptsTouchAt(const WindowInfo& windowInfo, int32_t displayId, float x, float y,
Prabir Pradhan33e3baa2022-12-06 20:30:22 +0000524 bool isStylus, const ui::Transform& displayTransform) {
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800525 const auto inputConfig = windowInfo.inputConfig;
526 if (windowInfo.displayId != displayId ||
527 inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800528 return false;
529 }
Prabir Pradhand65552b2021-10-07 11:23:50 -0700530 const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800531 if (inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800532 return false;
533 }
Prabir Pradhan33e3baa2022-12-06 20:30:22 +0000534
535 // Window Manager works in the logical display coordinate space. When it specifies bounds for a
536 // window as (l, t, r, b), the range of x in [l, r) and y in [t, b) are considered to be inside
537 // the window. Points on the right and bottom edges should not be inside the window, so we need
538 // to be careful about performing a hit test when the display is rotated, since the "right" and
539 // "bottom" of the window will be different in the display (un-rotated) space compared to in the
540 // logical display in which WM determined the bounds. Perform the hit test in the logical
541 // display space to ensure these edges are considered correctly in all orientations.
542 const auto touchableRegion = displayTransform.transform(windowInfo.touchableRegion);
543 const auto p = displayTransform.transform(x, y);
544 if (!touchableRegion.contains(std::floor(p.x), std::floor(p.y))) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800545 return false;
546 }
547 return true;
548}
549
Prabir Pradhand65552b2021-10-07 11:23:50 -0700550bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
551 return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
Prabir Pradhane5626962022-10-27 20:30:53 +0000552 isStylusToolType(entry.pointerProperties[pointerIndex].toolType);
Prabir Pradhand65552b2021-10-07 11:23:50 -0700553}
554
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800555// Determines if the given window can be targeted as InputTarget::Flags::FOREGROUND.
Prabir Pradhan6dfbf262022-03-14 15:24:30 +0000556// Foreground events are only sent to "foreground targetable" windows, but not all gestures sent to
557// such window are necessarily targeted with the flag. For example, an event with ACTION_OUTSIDE can
558// be sent to such a window, but it is not a foreground event and doesn't use
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800559// InputTarget::Flags::FOREGROUND.
Prabir Pradhan6dfbf262022-03-14 15:24:30 +0000560bool canReceiveForegroundTouches(const WindowInfo& info) {
561 // A non-touchable window can still receive touch events (e.g. in the case of
562 // STYLUS_INTERCEPTOR), so prevent such windows from receiving foreground events for touches.
563 return !info.inputConfig.test(gui::WindowInfo::InputConfig::NOT_TOUCHABLE) && !info.isSpy();
564}
565
Prabir Pradhanaeebeb42023-06-13 19:53:03 +0000566bool isWindowOwnedBy(const sp<WindowInfoHandle>& windowHandle, gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -0700567 if (windowHandle == nullptr) {
568 return false;
569 }
570 const WindowInfo* windowInfo = windowHandle->getInfo();
571 if (pid == windowInfo->ownerPid && uid == windowInfo->ownerUid) {
572 return true;
573 }
574 return false;
575}
576
Prabir Pradhan5735a322022-04-11 17:23:34 +0000577// Checks targeted injection using the window's owner's uid.
578// Returns an empty string if an entry can be sent to the given window, or an error message if the
579// entry is a targeted injection whose uid target doesn't match the window owner.
580std::optional<std::string> verifyTargetedInjection(const sp<WindowInfoHandle>& window,
581 const EventEntry& entry) {
582 if (entry.injectionState == nullptr || !entry.injectionState->targetUid) {
583 // The event was not injected, or the injected event does not target a window.
584 return {};
585 }
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000586 const auto uid = *entry.injectionState->targetUid;
Prabir Pradhan5735a322022-04-11 17:23:34 +0000587 if (window == nullptr) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000588 return StringPrintf("No valid window target for injection into uid %s.",
589 uid.toString().c_str());
Prabir Pradhan5735a322022-04-11 17:23:34 +0000590 }
591 if (entry.injectionState->targetUid != window->getInfo()->ownerUid) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000592 return StringPrintf("Injected event targeted at uid %s would be dispatched to window '%s' "
593 "owned by uid %s.",
594 uid.toString().c_str(), window->getName().c_str(),
595 window->getInfo()->ownerUid.toString().c_str());
Prabir Pradhan5735a322022-04-11 17:23:34 +0000596 }
597 return {};
598}
599
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000600std::pair<float, float> resolveTouchedPosition(const MotionEntry& entry) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700601 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
602 // Always dispatch mouse events to cursor position.
603 if (isFromMouse) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000604 return {entry.xCursorPosition, entry.yCursorPosition};
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700605 }
606
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -0700607 const int32_t pointerIndex = MotionEvent::getActionIndex(entry.action);
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000608 return {entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X),
609 entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y)};
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700610}
611
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -0700612std::optional<nsecs_t> getDownTime(const EventEntry& eventEntry) {
613 if (eventEntry.type == EventEntry::Type::KEY) {
614 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
615 return keyEntry.downTime;
616 } else if (eventEntry.type == EventEntry::Type::MOTION) {
617 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
618 return motionEntry.downTime;
619 }
620 return std::nullopt;
621}
622
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000623/**
624 * Compare the old touch state to the new touch state, and generate the corresponding touched
625 * windows (== input targets).
626 * If a window had the hovering pointer, but now it doesn't, produce HOVER_EXIT for that window.
627 * If the pointer just entered the new window, produce HOVER_ENTER.
628 * For pointers remaining in the window, produce HOVER_MOVE.
629 */
630std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState,
631 const TouchState& newTouchState,
632 const MotionEntry& entry) {
633 std::vector<TouchedWindow> out;
634 const int32_t maskedAction = MotionEvent::getActionMasked(entry.action);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -0700635
636 if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
637 // ACTION_SCROLL events should not affect the hovering pointer dispatch
638 return {};
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000639 }
640
641 // We should consider all hovering pointers here. But for now, just use the first one
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -0800642 const PointerProperties& pointer = entry.pointerProperties[0];
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000643
644 std::set<sp<WindowInfoHandle>> oldWindows;
645 if (oldState != nullptr) {
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -0800646 oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointer.id);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000647 }
648
649 std::set<sp<WindowInfoHandle>> newWindows =
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -0800650 newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointer.id);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000651
652 // If the pointer is no longer in the new window set, send HOVER_EXIT.
653 for (const sp<WindowInfoHandle>& oldWindow : oldWindows) {
654 if (newWindows.find(oldWindow) == newWindows.end()) {
655 TouchedWindow touchedWindow;
656 touchedWindow.windowHandle = oldWindow;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000657 touchedWindow.dispatchMode = InputTarget::DispatchMode::HOVER_EXIT;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000658 out.push_back(touchedWindow);
659 }
660 }
661
662 for (const sp<WindowInfoHandle>& newWindow : newWindows) {
663 TouchedWindow touchedWindow;
664 touchedWindow.windowHandle = newWindow;
665 if (oldWindows.find(newWindow) == oldWindows.end()) {
666 // Any windows that have this pointer now, and didn't have it before, should get
667 // HOVER_ENTER
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000668 touchedWindow.dispatchMode = InputTarget::DispatchMode::HOVER_ENTER;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000669 } else {
670 // This pointer was already sent to the window. Use ACTION_HOVER_MOVE.
Siarhei Vishniakouc2eb8502023-04-11 18:33:36 -0700671 if (CC_UNLIKELY(maskedAction != AMOTION_EVENT_ACTION_HOVER_MOVE)) {
Daniel Norman7487dfa2023-08-02 16:39:45 -0700672 android::base::LogSeverity severity = android::base::LogSeverity::FATAL;
Ameer Armalycff4fa52023-10-04 23:45:11 +0000673 if (!input_flags::a11y_crash_on_inconsistent_event_stream() &&
674 entry.flags & AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT) {
Daniel Norman7487dfa2023-08-02 16:39:45 -0700675 // The Accessibility injected touch exploration event stream
676 // has known inconsistencies, so log ERROR instead of
677 // crashing the device with FATAL.
Daniel Norman7487dfa2023-08-02 16:39:45 -0700678 severity = android::base::LogSeverity::ERROR;
679 }
680 LOG(severity) << "Expected ACTION_HOVER_MOVE instead of " << entry.getDescription();
Siarhei Vishniakouc2eb8502023-04-11 18:33:36 -0700681 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000682 touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000683 }
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -0800684 touchedWindow.addHoveringPointer(entry.deviceId, pointer);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000685 if (canReceiveForegroundTouches(*newWindow->getInfo())) {
686 touchedWindow.targetFlags |= InputTarget::Flags::FOREGROUND;
687 }
688 out.push_back(touchedWindow);
689 }
690 return out;
691}
692
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -0800693template <typename T>
694std::vector<T>& operator+=(std::vector<T>& left, const std::vector<T>& right) {
695 left.insert(left.end(), right.begin(), right.end());
696 return left;
697}
698
Harry Cuttsb166c002023-05-09 13:06:05 +0000699// Filter windows in a TouchState and targets in a vector to remove untrusted windows/targets from
700// both.
701void filterUntrustedTargets(TouchState& touchState, std::vector<InputTarget>& targets) {
702 std::erase_if(touchState.windows, [&](const TouchedWindow& window) {
703 if (!window.windowHandle->getInfo()->inputConfig.test(
704 WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
705 // In addition to TouchState, erase this window from the input targets! We don't have a
706 // good way to do this today except by adding a nested loop.
707 // TODO(b/282025641): simplify this code once InputTargets are being identified
708 // separately from TouchedWindows.
709 std::erase_if(targets, [&](const InputTarget& target) {
710 return target.inputChannel->getConnectionToken() == window.windowHandle->getToken();
711 });
712 return true;
713 }
714 return false;
715 });
716}
717
Siarhei Vishniakouce1fd472023-09-18 18:38:07 -0700718/**
719 * In general, touch should be always split between windows. Some exceptions:
720 * 1. Don't split touch if all of the below is true:
721 * (a) we have an active pointer down *and*
722 * (b) a new pointer is going down that's from the same device *and*
723 * (c) the window that's receiving the current pointer does not support split touch.
724 * 2. Don't split mouse events
725 */
726bool shouldSplitTouch(const TouchState& touchState, const MotionEntry& entry) {
727 if (isFromSource(entry.source, AINPUT_SOURCE_MOUSE)) {
728 // We should never split mouse events
729 return false;
730 }
731 for (const TouchedWindow& touchedWindow : touchState.windows) {
732 if (touchedWindow.windowHandle->getInfo()->isSpy()) {
733 // Spy windows should not affect whether or not touch is split.
734 continue;
735 }
736 if (touchedWindow.windowHandle->getInfo()->supportsSplitTouch()) {
737 continue;
738 }
739 if (touchedWindow.windowHandle->getInfo()->inputConfig.test(
740 gui::WindowInfo::InputConfig::IS_WALLPAPER)) {
741 // Wallpaper window should not affect whether or not touch is split
742 continue;
743 }
744
745 if (touchedWindow.hasTouchingPointers(entry.deviceId)) {
746 return false;
747 }
748 }
749 return true;
750}
751
Siarhei Vishniakouf77f60a2023-10-23 17:26:05 -0700752/**
753 * Return true if stylus is currently down anywhere on the specified display, and false otherwise.
754 */
755bool isStylusActiveInDisplay(
756 int32_t displayId,
757 const std::unordered_map<int32_t /*displayId*/, TouchState>& touchStatesByDisplay) {
758 const auto it = touchStatesByDisplay.find(displayId);
759 if (it == touchStatesByDisplay.end()) {
760 return false;
761 }
762 const TouchState& state = it->second;
763 return state.hasActiveStylus();
764}
765
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000766} // namespace
767
Michael Wrightd02c5b62014-02-10 15:10:22 -0800768// --- InputDispatcher ---
769
Prabir Pradhana41d2442023-04-20 21:30:40 +0000770InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy)
Garfield Tan00f511d2019-06-12 16:55:40 -0700771 : mPolicy(policy),
772 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700773 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800774 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700775 mAppSwitchSawKeyDown(false),
Colin Cross5b799302022-10-18 21:52:41 -0700776 mAppSwitchDueTime(LLONG_MAX),
Garfield Tan00f511d2019-06-12 16:55:40 -0700777 mNextUnblockedEvent(nullptr),
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800778 mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
Garfield Tan00f511d2019-06-12 16:55:40 -0700779 mDispatchEnabled(false),
780 mDispatchFrozen(false),
781 mInputFilterEnabled(false),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100782 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000783 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800784 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000785 mLatencyAggregator(),
Antonio Kantek15beb512022-06-13 22:35:41 +0000786 mLatencyTracker(&mLatencyAggregator) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700787 mLooper = sp<Looper>::make(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800788 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800789
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700790 mWindowInfoListener = sp<DispatcherWindowListener>::make(*this);
Siarhei Vishniakou31977182022-09-30 08:51:23 -0700791#if defined(__ANDROID__)
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700792 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
Siarhei Vishniakou31977182022-09-30 08:51:23 -0700793#endif
Yi Kong9b14ac62018-07-17 13:48:38 -0700794 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800795}
796
797InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000798 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800799
Prabir Pradhancef936d2021-07-21 16:17:52 +0000800 resetKeyRepeatLocked();
801 releasePendingEventLocked();
802 drainInboundQueueLocked();
803 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800804
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000805 while (!mConnectionsByToken.empty()) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -0700806 std::shared_ptr<Connection> connection = mConnectionsByToken.begin()->second;
Harry Cutts33476232023-01-30 19:57:29 +0000807 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), /*notify=*/false);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800808 }
809}
810
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700811status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700812 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700813 return ALREADY_EXISTS;
814 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700815 mThread = std::make_unique<InputThread>(
816 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
817 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700818}
819
820status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700821 if (mThread && mThread->isCallingThread()) {
822 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700823 return INVALID_OPERATION;
824 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700825 mThread.reset();
826 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700827}
828
Michael Wrightd02c5b62014-02-10 15:10:22 -0800829void InputDispatcher::dispatchOnce() {
Colin Cross5b799302022-10-18 21:52:41 -0700830 nsecs_t nextWakeupTime = LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800831 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800832 std::scoped_lock _l(mLock);
833 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800834
835 // Run a dispatch loop if there are no pending commands.
836 // The dispatch loop might enqueue commands to run afterwards.
837 if (!haveCommandsLocked()) {
838 dispatchOnceInnerLocked(&nextWakeupTime);
839 }
840
841 // Run all pending commands if there are any.
842 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000843 if (runCommandsLockedInterruptable()) {
Colin Cross5b799302022-10-18 21:52:41 -0700844 nextWakeupTime = LLONG_MIN;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800845 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800846
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700847 // If we are still waiting for ack on some events,
848 // we might have to wake up earlier to check if an app is anr'ing.
849 const nsecs_t nextAnrCheck = processAnrsLocked();
850 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
851
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800852 // We are about to enter an infinitely long sleep, because we have no commands or
853 // pending or queued events
Colin Cross5b799302022-10-18 21:52:41 -0700854 if (nextWakeupTime == LLONG_MAX) {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800855 mDispatcherEnteredIdle.notify_all();
856 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800857 } // release lock
858
859 // Wait for callback or timeout or wake. (make sure we round up, not down)
860 nsecs_t currentTime = now();
861 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
862 mLooper->pollOnce(timeoutMillis);
863}
864
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700865/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500866 * Raise ANR if there is no focused window.
867 * Before the ANR is raised, do a final state check:
868 * 1. The currently focused application must be the same one we are waiting for.
869 * 2. Ensure we still don't have a focused window.
870 */
871void InputDispatcher::processNoFocusedWindowAnrLocked() {
872 // Check if the application that we are waiting for is still focused.
873 std::shared_ptr<InputApplicationHandle> focusedApplication =
874 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
875 if (focusedApplication == nullptr ||
876 focusedApplication->getApplicationToken() !=
877 mAwaitedFocusedApplication->getApplicationToken()) {
878 // Unexpected because we should have reset the ANR timer when focused application changed
879 ALOGE("Waited for a focused window, but focused application has already changed to %s",
880 focusedApplication->getName().c_str());
881 return; // The focused application has changed.
882 }
883
chaviw98318de2021-05-19 16:45:23 -0500884 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500885 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
886 if (focusedWindowHandle != nullptr) {
887 return; // We now have a focused window. No need for ANR.
888 }
889 onAnrLocked(mAwaitedFocusedApplication);
890}
891
892/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700893 * Check if any of the connections' wait queues have events that are too old.
894 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
895 * Return the time at which we should wake up next.
896 */
897nsecs_t InputDispatcher::processAnrsLocked() {
898 const nsecs_t currentTime = now();
Colin Cross5b799302022-10-18 21:52:41 -0700899 nsecs_t nextAnrCheck = LLONG_MAX;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700900 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
901 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
902 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500903 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700904 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500905 mNoFocusedWindowTimeoutTime = std::nullopt;
Colin Cross5b799302022-10-18 21:52:41 -0700906 return LLONG_MIN;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700907 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500908 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700909 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
910 }
911 }
912
913 // Check if any connection ANRs are due
914 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
915 if (currentTime < nextAnrCheck) { // most likely scenario
916 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
917 }
918
919 // If we reached here, we have an unresponsive connection.
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -0700920 std::shared_ptr<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700921 if (connection == nullptr) {
922 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
923 return nextAnrCheck;
924 }
925 connection->responsive = false;
926 // Stop waking up for this unresponsive connection
927 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000928 onAnrLocked(connection);
Colin Cross5b799302022-10-18 21:52:41 -0700929 return LLONG_MIN;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700930}
931
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800932std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -0700933 const std::shared_ptr<Connection>& connection) {
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800934 if (connection->monitor) {
935 return mMonitorDispatchingTimeout;
936 }
937 const sp<WindowInfoHandle> window =
938 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700939 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500940 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700941 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500942 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700943}
944
Michael Wrightd02c5b62014-02-10 15:10:22 -0800945void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
946 nsecs_t currentTime = now();
947
Jeff Browndc5992e2014-04-11 01:27:26 -0700948 // Reset the key repeat timer whenever normal dispatch is suspended while the
949 // device is in a non-interactive state. This is to ensure that we abort a key
950 // repeat if the device is just coming out of sleep.
951 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800952 resetKeyRepeatLocked();
953 }
954
955 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
956 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100957 if (DEBUG_FOCUS) {
958 ALOGD("Dispatch frozen. Waiting some more.");
959 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800960 return;
961 }
962
963 // Optimize latency of app switches.
964 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
965 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
Siarhei Vishniakou6520a582023-10-27 21:53:45 -0700966 bool isAppSwitchDue;
Siarhei Vishniakou17f12282023-11-02 13:40:29 -0700967 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -0700968 isAppSwitchDue = mAppSwitchDueTime <= currentTime;
969 if (mAppSwitchDueTime < *nextWakeupTime) {
970 *nextWakeupTime = mAppSwitchDueTime;
971 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800972 }
973
974 // Ready to start a new event.
975 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700976 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700977 if (mInboundQueue.empty()) {
Siarhei Vishniakou17f12282023-11-02 13:40:29 -0700978 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -0700979 if (isAppSwitchDue) {
980 // The inbound queue is empty so the app switch key we were waiting
981 // for will never arrive. Stop waiting for it.
982 resetPendingAppSwitchLocked(false);
983 isAppSwitchDue = false;
984 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985 }
986
987 // Synthesize a key repeat if appropriate.
988 if (mKeyRepeatState.lastKeyEntry) {
989 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
990 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
991 } else {
992 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
993 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
994 }
995 }
996 }
997
998 // Nothing to do if there is no pending event.
999 if (!mPendingEvent) {
1000 return;
1001 }
1002 } else {
1003 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001004 mPendingEvent = mInboundQueue.front();
1005 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001006 traceInboundQueueLengthLocked();
1007 }
1008
1009 // Poke user activity for this event.
1010 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001011 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001012 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001013 }
1014
1015 // Now we have an event to dispatch.
1016 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -07001017 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001018 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001019 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001020 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001021 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001022 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001023 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001024 }
1025
1026 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001027 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001028 }
1029
1030 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001031 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001032 const ConfigurationChangedEntry& typedEntry =
1033 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001034 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001035 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001036 break;
1037 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001038
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001039 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001040 const DeviceResetEntry& typedEntry =
1041 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001042 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001043 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001044 break;
1045 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001046
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001047 case EventEntry::Type::FOCUS: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001048 std::shared_ptr<const FocusEntry> typedEntry =
1049 std::static_pointer_cast<const FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001050 dispatchFocusLocked(currentTime, typedEntry);
1051 done = true;
1052 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
1053 break;
1054 }
1055
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001056 case EventEntry::Type::TOUCH_MODE_CHANGED: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001057 const auto typedEntry = std::static_pointer_cast<const TouchModeEntry>(mPendingEvent);
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001058 dispatchTouchModeChangeLocked(currentTime, typedEntry);
1059 done = true;
1060 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
1061 break;
1062 }
1063
Prabir Pradhan99987712020-11-10 18:43:05 -08001064 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1065 const auto typedEntry =
Prabir Pradhan24047542023-11-02 17:14:59 +00001066 std::static_pointer_cast<const PointerCaptureChangedEntry>(mPendingEvent);
Prabir Pradhan99987712020-11-10 18:43:05 -08001067 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
1068 done = true;
1069 break;
1070 }
1071
arthurhungb89ccb02020-12-30 16:19:01 +08001072 case EventEntry::Type::DRAG: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001073 std::shared_ptr<const DragEntry> typedEntry =
1074 std::static_pointer_cast<const DragEntry>(mPendingEvent);
arthurhungb89ccb02020-12-30 16:19:01 +08001075 dispatchDragLocked(currentTime, typedEntry);
1076 done = true;
1077 break;
1078 }
1079
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001080 case EventEntry::Type::KEY: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001081 std::shared_ptr<const KeyEntry> keyEntry =
1082 std::static_pointer_cast<const KeyEntry>(mPendingEvent);
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001083 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001084 if (isAppSwitchDue) {
1085 if (isAppSwitchKeyEvent(*keyEntry)) {
1086 resetPendingAppSwitchLocked(true);
1087 isAppSwitchDue = false;
1088 } else if (dropReason == DropReason::NOT_DROPPED) {
1089 dropReason = DropReason::APP_SWITCH;
1090 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001091 }
1092 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001093 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001094 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001095 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001096 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
1097 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001098 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001099 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001100 break;
1101 }
1102
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001103 case EventEntry::Type::MOTION: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001104 std::shared_ptr<const MotionEntry> motionEntry =
1105 std::static_pointer_cast<const MotionEntry>(mPendingEvent);
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001106 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001107 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
1108 dropReason = DropReason::APP_SWITCH;
1109 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001110 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001111 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou6b71b632023-10-27 21:34:46 -07001112 // The event is stale. However, only drop stale events if there isn't an ongoing
1113 // gesture. That would allow us to complete the processing of the current stroke.
1114 const auto touchStateIt = mTouchStatesByDisplay.find(motionEntry->displayId);
1115 if (touchStateIt != mTouchStatesByDisplay.end()) {
1116 const TouchState& touchState = touchStateIt->second;
1117 if (!touchState.hasTouchingPointers(motionEntry->deviceId) &&
1118 !touchState.hasHoveringPointers(motionEntry->deviceId)) {
1119 dropReason = DropReason::STALE;
1120 }
1121 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001122 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001123 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
1124 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001125 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001126 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001127 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001128 }
Chris Yef59a2f42020-10-16 12:55:26 -07001129
1130 case EventEntry::Type::SENSOR: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001131 std::shared_ptr<const SensorEntry> sensorEntry =
1132 std::static_pointer_cast<const SensorEntry>(mPendingEvent);
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001133 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001134 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
1135 dropReason = DropReason::APP_SWITCH;
1136 }
Chris Yef59a2f42020-10-16 12:55:26 -07001137 }
1138 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
1139 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
1140 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
1141 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
1142 dropReason = DropReason::STALE;
1143 }
1144 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
1145 done = true;
1146 break;
1147 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001148 }
1149
1150 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001151 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001152 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001153 }
Michael Wright3a981722015-06-10 15:26:13 +01001154 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001155
1156 releasePendingEventLocked();
Colin Cross5b799302022-10-18 21:52:41 -07001157 *nextWakeupTime = LLONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -08001158 }
1159}
1160
Siarhei Vishniakou289e9242022-02-15 14:50:16 -08001161bool InputDispatcher::isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
Siarhei Vishniakoua7333112023-10-27 13:33:29 -07001162 return mPolicy.isStaleEvent(currentTime, entry.eventTime);
Siarhei Vishniakou289e9242022-02-15 14:50:16 -08001163}
1164
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001165/**
1166 * Return true if the events preceding this incoming motion event should be dropped
1167 * Return false otherwise (the default behaviour)
1168 */
1169bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001170 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001171 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001172
1173 // Optimize case where the current application is unresponsive and the user
1174 // decides to touch a window in a different application.
1175 // If the application takes too long to catch up then we drop all events preceding
1176 // the touch into the other window.
1177 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07001178 const int32_t displayId = motionEntry.displayId;
1179 const auto [x, y] = resolveTouchedPosition(motionEntry);
Harry Cutts33476232023-01-30 19:57:29 +00001180 const bool isStylus = isPointerFromStylus(motionEntry, /*pointerIndex=*/0);
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07001181
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001182 sp<WindowInfoHandle> touchedWindowHandle =
1183 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001184 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001185 touchedWindowHandle->getApplicationToken() !=
1186 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001187 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001188 ALOGI("Pruning input queue because user touched a different application while waiting "
1189 "for %s",
1190 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001191 return true;
1192 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001193
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001194 // Alternatively, maybe there's a spy window that could handle this event.
1195 const std::vector<sp<WindowInfoHandle>> touchedSpies =
1196 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
1197 for (const auto& windowHandle : touchedSpies) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07001198 const std::shared_ptr<Connection> connection =
1199 getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +00001200 if (connection != nullptr && connection->responsive) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001201 // This spy window could take more input. Drop all events preceding this
1202 // event, so that the spy window can get a chance to receive the stream.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001203 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001204 "responsive spy window that may handle the event.",
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001205 mAwaitedFocusedApplication->getName().c_str());
1206 return true;
1207 }
1208 }
1209 }
1210
1211 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
1212 // yet been processed by some connections, the dispatcher will wait for these motion
1213 // events to be processed before dispatching the key event. This is because these motion events
1214 // may cause a new window to be launched, which the user might expect to receive focus.
1215 // To prevent waiting forever for such events, just send the key to the currently focused window
1216 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
1217 ALOGD("Received a new pointer down event, stop waiting for events to process and "
1218 "just send the pending key event to the focused window.");
1219 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001220 }
1221 return false;
1222}
1223
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001224bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001225 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001226 mInboundQueue.push_back(std::move(newEntry));
Prabir Pradhan24047542023-11-02 17:14:59 +00001227 const EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001228 traceInboundQueueLengthLocked();
1229
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001230 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001231 case EventEntry::Type::KEY: {
Prabir Pradhan5735a322022-04-11 17:23:34 +00001232 LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1233 "Unexpected untrusted event.");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001234 // Optimize app switch latency.
1235 // If the application takes too long to catch up then we drop all events preceding
1236 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001237 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001238
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001239 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001240 if (isAppSwitchKeyEvent(keyEntry)) {
1241 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
1242 mAppSwitchSawKeyDown = true;
1243 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
1244 if (mAppSwitchSawKeyDown) {
1245 if (DEBUG_APP_SWITCH) {
1246 ALOGD("App switch is pending!");
1247 }
1248 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
1249 mAppSwitchSawKeyDown = false;
1250 needWake = true;
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001251 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001252 }
1253 }
1254 }
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001255 // If a new up event comes in, and the pending event with same key code has been asked
1256 // to try again later because of the policy. We have to reset the intercept key wake up
1257 // time for it may have been handled in the policy and could be dropped.
1258 if (keyEntry.action == AKEY_EVENT_ACTION_UP && mPendingEvent &&
1259 mPendingEvent->type == EventEntry::Type::KEY) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001260 const KeyEntry& pendingKey = static_cast<const KeyEntry&>(*mPendingEvent);
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001261 if (pendingKey.keyCode == keyEntry.keyCode &&
1262 pendingKey.interceptKeyResult ==
Michael Wright5caf55a2022-11-24 22:31:42 +00001263 KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
1264 pendingKey.interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001265 pendingKey.interceptKeyWakeupTime = 0;
1266 needWake = true;
1267 }
1268 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001269 break;
1270 }
1271
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001272 case EventEntry::Type::MOTION: {
Prabir Pradhan5735a322022-04-11 17:23:34 +00001273 LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1274 "Unexpected untrusted event.");
Prabir Pradhan24047542023-11-02 17:14:59 +00001275 if (shouldPruneInboundQueueLocked(static_cast<const MotionEntry&>(entry))) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001276 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001277 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001278 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001279 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001280 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001281 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001282 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1283 break;
1284 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001285 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001286 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001287 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001288 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001289 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1290 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001291 // nothing to do
1292 break;
1293 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001294 }
1295
1296 return needWake;
1297}
1298
Prabir Pradhan24047542023-11-02 17:14:59 +00001299void InputDispatcher::addRecentEventLocked(std::shared_ptr<const EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001300 // Do not store sensor event in recent queue to avoid flooding the queue.
1301 if (entry->type != EventEntry::Type::SENSOR) {
1302 mRecentQueue.push_back(entry);
1303 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001304 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001305 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001306 }
1307}
1308
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001309sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, float x, float y,
1310 bool isStylus,
1311 bool ignoreDragWindow) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001312 // Traverse windows from front to back to find touched window.
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001313 const auto& windowHandles = getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05001314 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001315 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001316 continue;
1317 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001318
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001319 const WindowInfo& info = *windowHandle->getInfo();
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00001320 if (!info.isSpy() &&
1321 windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001322 return windowHandle;
1323 }
1324 }
1325 return nullptr;
1326}
1327
1328std::vector<InputTarget> InputDispatcher::findOutsideTargetsLocked(
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07001329 int32_t displayId, const sp<WindowInfoHandle>& touchedWindow, int32_t pointerId) const {
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001330 if (touchedWindow == nullptr) {
1331 return {};
1332 }
1333 // Traverse windows from front to back until we encounter the touched window.
1334 std::vector<InputTarget> outsideTargets;
1335 const auto& windowHandles = getWindowHandlesLocked(displayId);
1336 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1337 if (windowHandle == touchedWindow) {
1338 // Stop iterating once we found a touched window. Any WATCH_OUTSIDE_TOUCH window
1339 // below the touched window will not get ACTION_OUTSIDE event.
1340 return outsideTargets;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001341 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001342
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001343 const WindowInfo& info = *windowHandle->getInfo();
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08001344 if (info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07001345 std::bitset<MAX_POINTER_ID + 1> pointerIds;
1346 pointerIds.set(pointerId);
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00001347 addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::OUTSIDE,
1348 ftl::Flags<InputTarget::Flags>(), pointerIds,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07001349 /*firstDownTimeInTarget=*/std::nullopt, outsideTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001350 }
1351 }
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001352 return outsideTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001353}
1354
Prabir Pradhand65552b2021-10-07 11:23:50 -07001355std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
Prabir Pradhan82e081e2022-12-06 09:50:09 +00001356 int32_t displayId, float x, float y, bool isStylus) const {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001357 // Traverse windows from front to back and gather the touched spy windows.
1358 std::vector<sp<WindowInfoHandle>> spyWindows;
1359 const auto& windowHandles = getWindowHandlesLocked(displayId);
1360 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1361 const WindowInfo& info = *windowHandle->getInfo();
1362
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00001363 if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001364 continue;
1365 }
1366 if (!info.isSpy()) {
1367 // The first touched non-spy window was found, so return the spy windows touched so far.
1368 return spyWindows;
1369 }
1370 spyWindows.push_back(windowHandle);
1371 }
1372 return spyWindows;
1373}
1374
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001375void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001376 const char* reason;
1377 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001378 case DropReason::POLICY:
Prabir Pradhan65613802023-02-22 23:36:58 +00001379 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001380 ALOGD("Dropped event because policy consumed it.");
1381 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001382 reason = "inbound event was dropped because the policy consumed it";
1383 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001384 case DropReason::DISABLED:
1385 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001386 ALOGI("Dropped event because input dispatch is disabled.");
1387 }
1388 reason = "inbound event was dropped because input dispatch is disabled";
1389 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001390 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001391 ALOGI("Dropped event because of pending overdue app switch.");
1392 reason = "inbound event was dropped because of pending overdue app switch";
1393 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001394 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001395 ALOGI("Dropped event because the current application is not responding and the user "
1396 "has started interacting with a different application.");
1397 reason = "inbound event was dropped because the current application is not responding "
1398 "and the user has started interacting with a different application";
1399 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001400 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001401 ALOGI("Dropped event because it is stale.");
1402 reason = "inbound event was dropped because it is stale";
1403 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001404 case DropReason::NO_POINTER_CAPTURE:
1405 ALOGI("Dropped event because there is no window with Pointer Capture.");
1406 reason = "inbound event was dropped because there is no window with Pointer Capture";
1407 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001408 case DropReason::NOT_DROPPED: {
1409 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001410 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001411 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001412 }
1413
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001414 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001415 case EventEntry::Type::KEY: {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001416 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001417 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001418 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001419 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001420 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001421 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1422 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001423 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, reason);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001424 synthesizeCancelationEventsForAllConnectionsLocked(options);
1425 } else {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001426 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
1427 reason);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001428 synthesizeCancelationEventsForAllConnectionsLocked(options);
1429 }
1430 break;
1431 }
Chris Yef59a2f42020-10-16 12:55:26 -07001432 case EventEntry::Type::SENSOR: {
1433 break;
1434 }
arthurhungb89ccb02020-12-30 16:19:01 +08001435 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1436 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001437 break;
1438 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001439 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001440 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001441 case EventEntry::Type::CONFIGURATION_CHANGED:
1442 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001443 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001444 break;
1445 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001446 }
1447}
1448
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001449static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001450 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1451 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001452}
1453
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001454bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1455 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1456 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1457 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001458}
1459
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07001460bool InputDispatcher::isAppSwitchPendingLocked() const {
Colin Cross5b799302022-10-18 21:52:41 -07001461 return mAppSwitchDueTime != LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001462}
1463
1464void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
Colin Cross5b799302022-10-18 21:52:41 -07001465 mAppSwitchDueTime = LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001466
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001467 if (DEBUG_APP_SWITCH) {
1468 if (handled) {
1469 ALOGD("App switch has arrived.");
1470 } else {
1471 ALOGD("App switch was abandoned.");
1472 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001473 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001474}
1475
Michael Wrightd02c5b62014-02-10 15:10:22 -08001476bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001477 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001478}
1479
Prabir Pradhancef936d2021-07-21 16:17:52 +00001480bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001481 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001482 return false;
1483 }
1484
1485 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001486 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001487 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001488 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1489 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001490 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001491 return true;
1492}
1493
Prabir Pradhancef936d2021-07-21 16:17:52 +00001494void InputDispatcher::postCommandLocked(Command&& command) {
1495 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001496}
1497
1498void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001499 while (!mInboundQueue.empty()) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001500 std::shared_ptr<const EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001501 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001502 releaseInboundEventLocked(entry);
1503 }
1504 traceInboundQueueLengthLocked();
1505}
1506
1507void InputDispatcher::releasePendingEventLocked() {
1508 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001509 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001510 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001511 }
1512}
1513
Prabir Pradhan24047542023-11-02 17:14:59 +00001514void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<const EventEntry> entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00001515 const std::shared_ptr<InjectionState>& injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001516 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001517 if (DEBUG_DISPATCH_CYCLE) {
1518 ALOGD("Injected inbound event was dropped.");
1519 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001520 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001521 }
1522 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001523 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001524 }
1525 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001526}
1527
1528void InputDispatcher::resetKeyRepeatLocked() {
1529 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001530 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001531 }
1532}
1533
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001534std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001535 std::shared_ptr<const KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001536
Michael Wright2e732952014-09-24 13:26:59 -07001537 uint32_t policyFlags = entry->policyFlags &
1538 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001539
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001540 std::shared_ptr<KeyEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00001541 std::make_unique<KeyEntry>(mIdGenerator.nextId(), /*injectionState=*/nullptr,
1542 currentTime, entry->deviceId, entry->source,
1543 entry->displayId, policyFlags, entry->action, entry->flags,
1544 entry->keyCode, entry->scanCode, entry->metaState,
1545 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001546
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001547 newEntry->syntheticRepeat = true;
1548 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001549 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001550 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001551}
1552
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001553bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001554 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001555 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1556 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1557 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001558
1559 // Reset key repeating in case a keyboard device was added or removed or something.
1560 resetKeyRepeatLocked();
1561
1562 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001563 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1564 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00001565 mPolicy.notifyConfigurationChanged(eventTime);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001566 };
1567 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001568 return true;
1569}
1570
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001571bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1572 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001573 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1574 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1575 entry.deviceId);
1576 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001577
liushenxiang42232912021-05-21 20:24:09 +08001578 // Reset key repeating in case a keyboard device was disabled or enabled.
1579 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1580 resetKeyRepeatLocked();
1581 }
1582
Michael Wrightfb04fd52022-11-24 22:31:11 +00001583 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001584 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001585 synthesizeCancelationEventsForAllConnectionsLocked(options);
Siarhei Vishniakou0686f0c2023-05-02 11:56:15 -07001586
1587 // Remove all active pointers from this device
1588 for (auto& [_, touchState] : mTouchStatesByDisplay) {
1589 touchState.removeAllPointersForDevice(entry.deviceId);
1590 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001591 return true;
1592}
1593
Vishnu Nairad321cd2020-08-20 16:40:21 -07001594void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001595 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001596 if (mPendingEvent != nullptr) {
1597 // Move the pending event to the front of the queue. This will give the chance
1598 // for the pending event to get dispatched to the newly focused window
1599 mInboundQueue.push_front(mPendingEvent);
1600 mPendingEvent = nullptr;
1601 }
1602
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001603 std::unique_ptr<FocusEntry> focusEntry =
1604 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1605 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001606
1607 // This event should go to the front of the queue, but behind all other focus events
1608 // Find the last focus event, and insert right after it
Prabir Pradhan24047542023-11-02 17:14:59 +00001609 auto it = std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
1610 [](const std::shared_ptr<const EventEntry>& event) {
1611 return event->type == EventEntry::Type::FOCUS;
1612 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001613
1614 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001615 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001616}
1617
Prabir Pradhan24047542023-11-02 17:14:59 +00001618void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime,
1619 std::shared_ptr<const FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001620 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001621 if (channel == nullptr) {
1622 return; // Window has gone away
1623 }
1624 InputTarget target;
1625 target.inputChannel = channel;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001626 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001627 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1628 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001629 std::string reason = std::string("reason=").append(entry->reason);
1630 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001631 dispatchEventLocked(currentTime, entry, {target});
1632}
1633
Prabir Pradhan99987712020-11-10 18:43:05 -08001634void InputDispatcher::dispatchPointerCaptureChangedLocked(
Prabir Pradhan24047542023-11-02 17:14:59 +00001635 nsecs_t currentTime, const std::shared_ptr<const PointerCaptureChangedEntry>& entry,
Prabir Pradhan99987712020-11-10 18:43:05 -08001636 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001637 dropReason = DropReason::NOT_DROPPED;
1638
Prabir Pradhan99987712020-11-10 18:43:05 -08001639 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001640 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001641
1642 if (entry->pointerCaptureRequest.enable) {
1643 // Enable Pointer Capture.
1644 if (haveWindowWithPointerCapture &&
1645 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
Prabir Pradhan7092e262022-05-03 16:51:09 +00001646 // This can happen if pointer capture is disabled and re-enabled before we notify the
1647 // app of the state change, so there is no need to notify the app.
1648 ALOGI("Skipping dispatch of Pointer Capture being enabled: no state change.");
1649 return;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001650 }
1651 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001652 // This can happen if a window requests capture and immediately releases capture.
1653 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001654 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001655 return;
1656 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001657 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1658 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1659 return;
1660 }
1661
Vishnu Nairc519ff72021-01-21 08:23:08 -08001662 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001663 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1664 mWindowTokenWithPointerCapture = token;
1665 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001666 // Disable Pointer Capture.
1667 // We do not check if the sequence number matches for requests to disable Pointer Capture
1668 // for two reasons:
1669 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1670 // to disable capture with the same sequence number: one generated by
1671 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1672 // Capture being disabled in InputReader.
1673 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1674 // actual Pointer Capture state that affects events being generated by input devices is
1675 // in InputReader.
1676 if (!haveWindowWithPointerCapture) {
1677 // Pointer capture was already forcefully disabled because of focus change.
1678 dropReason = DropReason::NOT_DROPPED;
1679 return;
1680 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001681 token = mWindowTokenWithPointerCapture;
1682 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001683 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001684 setPointerCaptureLocked(false);
1685 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001686 }
1687
1688 auto channel = getInputChannelLocked(token);
1689 if (channel == nullptr) {
1690 // Window has gone away, clean up Pointer Capture state.
1691 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001692 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001693 setPointerCaptureLocked(false);
1694 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001695 return;
1696 }
1697 InputTarget target;
1698 target.inputChannel = channel;
Prabir Pradhan99987712020-11-10 18:43:05 -08001699 entry->dispatchInProgress = true;
1700 dispatchEventLocked(currentTime, entry, {target});
1701
1702 dropReason = DropReason::NOT_DROPPED;
1703}
1704
Prabir Pradhan24047542023-11-02 17:14:59 +00001705void InputDispatcher::dispatchTouchModeChangeLocked(
1706 nsecs_t currentTime, const std::shared_ptr<const TouchModeEntry>& entry) {
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001707 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Antonio Kantek15beb512022-06-13 22:35:41 +00001708 getWindowHandlesLocked(entry->displayId);
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001709 if (windowHandles.empty()) {
1710 return;
1711 }
1712 const std::vector<InputTarget> inputTargets =
1713 getInputTargetsFromWindowHandlesLocked(windowHandles);
1714 if (inputTargets.empty()) {
1715 return;
1716 }
1717 entry->dispatchInProgress = true;
1718 dispatchEventLocked(currentTime, entry, inputTargets);
1719}
1720
1721std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1722 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1723 std::vector<InputTarget> inputTargets;
1724 for (const sp<WindowInfoHandle>& handle : windowHandles) {
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001725 const sp<IBinder>& token = handle->getToken();
1726 if (token == nullptr) {
1727 continue;
1728 }
1729 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1730 if (channel == nullptr) {
1731 continue; // Window has gone away
1732 }
1733 InputTarget target;
1734 target.inputChannel = channel;
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001735 inputTargets.push_back(target);
1736 }
1737 return inputTargets;
1738}
1739
Prabir Pradhan24047542023-11-02 17:14:59 +00001740bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001741 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001742 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001743 if (!entry->dispatchInProgress) {
1744 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1745 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1746 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1747 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001748 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001749 // We have seen two identical key downs in a row which indicates that the device
1750 // driver is automatically generating key repeats itself. We take note of the
1751 // repeat here, but we disable our own next key repeat timer since it is clear that
1752 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001753 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1754 // Make sure we don't get key down from a different device. If a different
1755 // device Id has same key pressed down, the new device Id will replace the
1756 // current one to hold the key repeat with repeat count reset.
1757 // In the future when got a KEY_UP on the device id, drop it and do not
1758 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001759 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1760 resetKeyRepeatLocked();
Colin Cross5b799302022-10-18 21:52:41 -07001761 mKeyRepeatState.nextRepeatTime = LLONG_MAX; // don't generate repeats ourselves
Michael Wrightd02c5b62014-02-10 15:10:22 -08001762 } else {
1763 // Not a repeat. Save key down state in case we do see a repeat later.
1764 resetKeyRepeatLocked();
1765 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1766 }
1767 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001768 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1769 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001770 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan65613802023-02-22 23:36:58 +00001771 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001772 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1773 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001774 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001775 resetKeyRepeatLocked();
1776 }
1777
1778 if (entry->repeatCount == 1) {
1779 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1780 } else {
1781 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1782 }
1783
1784 entry->dispatchInProgress = true;
1785
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001786 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001787 }
1788
1789 // Handle case where the policy asked us to try again later last time.
Michael Wright5caf55a2022-11-24 22:31:42 +00001790 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001791 if (currentTime < entry->interceptKeyWakeupTime) {
1792 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1793 *nextWakeupTime = entry->interceptKeyWakeupTime;
1794 }
1795 return false; // wait until next wakeup
1796 }
Michael Wright5caf55a2022-11-24 22:31:42 +00001797 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001798 entry->interceptKeyWakeupTime = 0;
1799 }
1800
1801 // Give the policy a chance to intercept the key.
Michael Wright5caf55a2022-11-24 22:31:42 +00001802 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001803 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001804 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001805 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001806
1807 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1808 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1809 };
1810 postCommandLocked(std::move(command));
Josep del Riob3981622023-04-18 15:49:45 +00001811 // Poke user activity for keys not passed to user
1812 pokeUserActivityLocked(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001813 return false; // wait for the command to run
1814 } else {
Michael Wright5caf55a2022-11-24 22:31:42 +00001815 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001816 }
Michael Wright5caf55a2022-11-24 22:31:42 +00001817 } else if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001818 if (*dropReason == DropReason::NOT_DROPPED) {
1819 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001820 }
1821 }
1822
1823 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001824 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001825 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001826 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1827 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001828 mReporter->reportDroppedKey(entry->id);
Josep del Riob3981622023-04-18 15:49:45 +00001829 // Poke user activity for undispatched keys
1830 pokeUserActivityLocked(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001831 return true;
1832 }
1833
1834 // Identify targets.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001835 InputEventInjectionResult injectionResult;
1836 sp<WindowInfoHandle> focusedWindow =
1837 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime,
1838 /*byref*/ injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001839 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001840 return false;
1841 }
1842
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001843 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001844 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001845 return true;
1846 }
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001847 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
1848
1849 std::vector<InputTarget> inputTargets;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00001850 addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
1851 InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001852
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001853 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001854 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001855
1856 // Dispatch the key.
1857 dispatchEventLocked(currentTime, entry, inputTargets);
1858 return true;
1859}
1860
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001861void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001862 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1863 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1864 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1865 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1866 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1867 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1868 entry.metaState, entry.repeatCount, entry.downTime);
1869 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001870}
1871
Prabir Pradhancef936d2021-07-21 16:17:52 +00001872void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
Prabir Pradhan24047542023-11-02 17:14:59 +00001873 const std::shared_ptr<const SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001874 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001875 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1876 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1877 "source=0x%x, sensorType=%s",
1878 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001879 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001880 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001881 auto command = [this, entry]() REQUIRES(mLock) {
1882 scoped_unlock unlock(mLock);
1883
1884 if (entry->accuracyChanged) {
Prabir Pradhana41d2442023-04-20 21:30:40 +00001885 mPolicy.notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001886 }
Prabir Pradhana41d2442023-04-20 21:30:40 +00001887 mPolicy.notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1888 entry->hwTimestamp, entry->values);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001889 };
1890 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001891}
1892
1893bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001894 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1895 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001896 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001897 }
Chris Yef59a2f42020-10-16 12:55:26 -07001898 { // acquire lock
1899 std::scoped_lock _l(mLock);
1900
1901 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001902 std::shared_ptr<const EventEntry> entry = *it;
Chris Yef59a2f42020-10-16 12:55:26 -07001903 if (entry->type == EventEntry::Type::SENSOR) {
1904 it = mInboundQueue.erase(it);
1905 releaseInboundEventLocked(entry);
1906 }
1907 }
1908 }
1909 return true;
1910}
1911
Prabir Pradhan24047542023-11-02 17:14:59 +00001912bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime,
1913 std::shared_ptr<const MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001914 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001915 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001916 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001917 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001918 entry->dispatchInProgress = true;
1919
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001920 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001921 }
1922
1923 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001924 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001925 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001926 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1927 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001928 return true;
1929 }
1930
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001931 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001932
1933 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001934 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001935
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001936 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001937 if (isPointerEvent) {
1938 // Pointer event. (eg. touchscreen)
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00001939
1940 if (mDragState &&
1941 (entry->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN) {
1942 // If drag and drop ongoing and pointer down occur: pilfer drag window pointers
1943 pilferPointersLocked(mDragState->dragWindow->getToken());
1944 }
1945
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08001946 inputTargets =
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07001947 findTouchedWindowTargetsLocked(currentTime, *entry, /*byref*/ injectionResult);
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08001948 LOG_ALWAYS_FATAL_IF(injectionResult != InputEventInjectionResult::SUCCEEDED &&
1949 !inputTargets.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001950 } else {
1951 // Non touch event. (eg. trackball)
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001952 sp<WindowInfoHandle> focusedWindow =
1953 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime, injectionResult);
1954 if (injectionResult == InputEventInjectionResult::SUCCEEDED) {
1955 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00001956 addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
1957 InputTarget::Flags::FOREGROUND, getDownTime(*entry),
1958 inputTargets);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001959 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001960 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001961 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001962 return false;
1963 }
1964
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001965 setInjectionResult(*entry, injectionResult);
Prabir Pradhan5735a322022-04-11 17:23:34 +00001966 if (injectionResult == InputEventInjectionResult::TARGET_MISMATCH) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001967 return true;
1968 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001969 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001970 CancelationOptions::Mode mode(
1971 isPointerEvent ? CancelationOptions::Mode::CANCEL_POINTER_EVENTS
1972 : CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS);
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001973 CancelationOptions options(mode, "input event injection failed");
1974 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001975 return true;
1976 }
1977
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001978 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001979 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001980
1981 // Dispatch the motion.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001982 dispatchEventLocked(currentTime, entry, inputTargets);
1983 return true;
1984}
1985
chaviw98318de2021-05-19 16:45:23 -05001986void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
Arthur Hung54745652022-04-20 07:17:41 +00001987 bool isExiting, const int32_t rawX,
1988 const int32_t rawY) {
1989 const vec2 xy = windowHandle->getInfo()->transform.transform(vec2(rawX, rawY));
arthurhungb89ccb02020-12-30 16:19:01 +08001990 std::unique_ptr<DragEntry> dragEntry =
Arthur Hung54745652022-04-20 07:17:41 +00001991 std::make_unique<DragEntry>(mIdGenerator.nextId(), now(), windowHandle->getToken(),
1992 isExiting, xy.x, xy.y);
arthurhungb89ccb02020-12-30 16:19:01 +08001993
1994 enqueueInboundEventLocked(std::move(dragEntry));
1995}
1996
Prabir Pradhan24047542023-11-02 17:14:59 +00001997void InputDispatcher::dispatchDragLocked(nsecs_t currentTime,
1998 std::shared_ptr<const DragEntry> entry) {
arthurhungb89ccb02020-12-30 16:19:01 +08001999 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
2000 if (channel == nullptr) {
2001 return; // Window has gone away
2002 }
2003 InputTarget target;
2004 target.inputChannel = channel;
arthurhungb89ccb02020-12-30 16:19:01 +08002005 entry->dispatchInProgress = true;
2006 dispatchEventLocked(currentTime, entry, {target});
2007}
2008
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002009void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002010 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08002011 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=%s, displayId=%" PRId32
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002012 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00002013 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002014 "metaState=0x%x, buttonState=0x%x,"
2015 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08002016 prefix, entry.eventTime, entry.deviceId,
2017 inputEventSourceToString(entry.source).c_str(), entry.displayId, entry.policyFlags,
2018 MotionEvent::actionToString(entry.action).c_str(), entry.actionButton, entry.flags,
2019 entry.metaState, entry.buttonState, entry.edgeFlags, entry.xPrecision,
2020 entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002021
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002022 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
Siarhei Vishniakou09a8fe42022-07-21 17:27:03 -07002023 ALOGD(" Pointer %d: id=%d, toolType=%s, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002024 "x=%f, y=%f, pressure=%f, size=%f, "
2025 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2026 "orientation=%f",
Siarhei Vishniakou09a8fe42022-07-21 17:27:03 -07002027 i, entry.pointerProperties[i].id,
2028 ftl::enum_string(entry.pointerProperties[i].toolType).c_str(),
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002029 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2030 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2031 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2032 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2033 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2034 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2035 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2036 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2037 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2038 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002039 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002040}
2041
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002042void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
Prabir Pradhan24047542023-11-02 17:14:59 +00002043 std::shared_ptr<const EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002044 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002045 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002046 if (DEBUG_DISPATCH_CYCLE) {
2047 ALOGD("dispatchEventToCurrentInputTargets");
2048 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002049
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00002050 processInteractionsLocked(*eventEntry, inputTargets);
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002051
Michael Wrightd02c5b62014-02-10 15:10:22 -08002052 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
2053
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002054 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002055
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002056 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002057 std::shared_ptr<Connection> connection =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002058 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002059 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002060 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002061 } else {
Siarhei Vishniakou31dd1552023-10-30 18:46:10 -07002062 if (DEBUG_DROPPED_EVENTS_VERBOSE) {
2063 LOG(INFO) << "Dropping event delivery to target with channel "
2064 << inputTarget.inputChannel->getName()
2065 << " because it is no longer registered with the input dispatcher.";
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002066 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067 }
2068 }
2069}
2070
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002071void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002072 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
2073 // If the policy decides to close the app, we will get a channel removal event via
2074 // unregisterInputChannel, and will clean up the connection that way. We are already not
2075 // sending new pointers to the connection when it blocked, but focused events will continue to
2076 // pile up.
2077 ALOGW("Canceling events for %s because it is unresponsive",
2078 connection->inputChannel->getName().c_str());
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002079 if (connection->status == Connection::Status::NORMAL) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00002080 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002081 "application not responding");
2082 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002083 }
2084}
2085
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002086void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002087 if (DEBUG_FOCUS) {
2088 ALOGD("Resetting ANR timeouts.");
2089 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002090
2091 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002092 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07002093 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002094}
2095
Tiger Huang721e26f2018-07-24 22:26:19 +08002096/**
2097 * Get the display id that the given event should go to. If this event specifies a valid display id,
2098 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
2099 * Focused display is the display that the user most recently interacted with.
2100 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002101int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08002102 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002103 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002104 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002105 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2106 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002107 break;
2108 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002109 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002110 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2111 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002112 break;
2113 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002114 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002115 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002116 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002117 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07002118 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08002119 case EventEntry::Type::SENSOR:
2120 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08002121 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002122 return ADISPLAY_ID_NONE;
2123 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002124 }
2125 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
2126}
2127
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002128bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
2129 const char* focusedWindowName) {
2130 if (mAnrTracker.empty()) {
2131 // already processed all events that we waited for
2132 mKeyIsWaitingForEventsTimeout = std::nullopt;
2133 return false;
2134 }
2135
2136 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
2137 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002138 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002139 mKeyIsWaitingForEventsTimeout = currentTime +
2140 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
2141 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002142 return true;
2143 }
2144
2145 // We still have pending events, and already started the timer
2146 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
2147 return true; // Still waiting
2148 }
2149
2150 // Waited too long, and some connection still hasn't processed all motions
2151 // Just send the key to the focused window
2152 ALOGW("Dispatching key to %s even though there are other unprocessed events",
2153 focusedWindowName);
2154 mKeyIsWaitingForEventsTimeout = std::nullopt;
2155 return false;
2156}
2157
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002158sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked(
2159 nsecs_t currentTime, const EventEntry& entry, nsecs_t* nextWakeupTime,
2160 InputEventInjectionResult& outInjectionResult) {
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002161 outInjectionResult = InputEventInjectionResult::FAILED; // Default result
Michael Wrightd02c5b62014-02-10 15:10:22 -08002162
Tiger Huang721e26f2018-07-24 22:26:19 +08002163 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05002164 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07002165 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08002166 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
2167
Michael Wrightd02c5b62014-02-10 15:10:22 -08002168 // If there is no currently focused window and no focused application
2169 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002170 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
2171 ALOGI("Dropping %s event because there is no focused window or focused application in "
2172 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08002173 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002174 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002175 }
2176
Vishnu Nair062a8672021-09-03 16:07:44 -07002177 // Drop key events if requested by input feature
2178 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002179 return nullptr;
Vishnu Nair062a8672021-09-03 16:07:44 -07002180 }
2181
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002182 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
2183 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
2184 // start interacting with another application via touch (app switch). This code can be removed
2185 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
2186 // an app is expected to have a focused window.
2187 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
2188 if (!mNoFocusedWindowTimeoutTime.has_value()) {
2189 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05002190 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
2191 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
2192 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002193 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05002194 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002195 ALOGW("Waiting because no window has focus but %s may eventually add a "
2196 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05002197 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002198 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002199 outInjectionResult = InputEventInjectionResult::PENDING;
2200 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002201 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
2202 // Already raised ANR. Drop the event
2203 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08002204 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002205 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002206 } else {
2207 // Still waiting for the focused window
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002208 outInjectionResult = InputEventInjectionResult::PENDING;
2209 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002210 }
2211 }
2212
2213 // we have a valid, non-null focused window
2214 resetNoFocusedWindowTimeoutLocked();
2215
Prabir Pradhan5735a322022-04-11 17:23:34 +00002216 // Verify targeted injection.
2217 if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) {
2218 ALOGW("Dropping injected event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002219 outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
2220 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002221 }
2222
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002223 if (focusedWindowHandle->getInfo()->inputConfig.test(
2224 WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002225 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002226 outInjectionResult = InputEventInjectionResult::PENDING;
2227 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002228 }
2229
2230 // If the event is a key event, then we must wait for all previous events to
2231 // complete before delivering it because previous events may have the
2232 // side-effect of transferring focus to a different window and we want to
2233 // ensure that the following keys are sent to the new window.
2234 //
2235 // Suppose the user touches a button in a window then immediately presses "A".
2236 // If the button causes a pop-up window to appear then we want to ensure that
2237 // the "A" key is delivered to the new pop-up window. This is because users
2238 // often anticipate pending UI changes when typing on a keyboard.
2239 // To obtain this behavior, we must serialize key events with respect to all
2240 // prior input events.
2241 if (entry.type == EventEntry::Type::KEY) {
2242 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
2243 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002244 outInjectionResult = InputEventInjectionResult::PENDING;
2245 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002246 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002247 }
2248
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002249 outInjectionResult = InputEventInjectionResult::SUCCEEDED;
2250 return focusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002251}
2252
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002253/**
2254 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
2255 * that are currently unresponsive.
2256 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002257std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
2258 const std::vector<Monitor>& monitors) const {
2259 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002260 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002261 [this](const Monitor& monitor) REQUIRES(mLock) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002262 std::shared_ptr<Connection> connection =
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002263 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002264 if (connection == nullptr) {
2265 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002266 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002267 return false;
2268 }
2269 if (!connection->responsive) {
2270 ALOGW("Unresponsive monitor %s will not get the new gesture",
2271 connection->inputChannel->getName().c_str());
2272 return false;
2273 }
2274 return true;
2275 });
2276 return responsiveMonitors;
2277}
2278
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002279std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002280 nsecs_t currentTime, const MotionEntry& entry,
Siarhei Vishniakou4fe57392022-10-25 13:44:30 -07002281 InputEventInjectionResult& outInjectionResult) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002282 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002283
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002284 std::vector<InputTarget> targets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002285 // For security reasons, we defer updating the touch state until we are sure that
2286 // event injection will be allowed.
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002287 const int32_t displayId = entry.displayId;
2288 const int32_t action = entry.action;
Siarhei Vishniakoubf880522023-05-01 11:03:22 -07002289 const int32_t maskedAction = MotionEvent::getActionMasked(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002290
2291 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002292 outInjectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002293
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002294 // Copy current touch state into tempTouchState.
2295 // This state will be used to update mTouchStatesByDisplay at the end of this function.
2296 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07002297 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002298 TouchState tempTouchState;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002299 if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
2300 oldState = &(it->second);
Prabir Pradhane680f9b2022-02-04 04:24:00 -08002301 tempTouchState = *oldState;
Jeff Brownf086ddb2014-02-11 14:28:48 -08002302 }
2303
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002304 bool isSplit = shouldSplitTouch(tempTouchState, entry);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002305
2306 const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2307 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2308 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002309 // A DOWN could be generated from POINTER_DOWN if the initial pointers did not land into any
2310 // touchable windows.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002311 const bool wasDown = oldState != nullptr && oldState->isDown(entry.deviceId);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002312 const bool isDown = (maskedAction == AMOTION_EVENT_ACTION_DOWN) ||
2313 (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN && !wasDown);
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002314 const bool newGesture = isDown || maskedAction == AMOTION_EVENT_ACTION_SCROLL ||
2315 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2316 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE;
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002317 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Siarhei Vishniakou5cee1e32022-11-29 12:35:39 -08002318
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002319 if (newGesture) {
2320 isSplit = false;
Siarhei Vishniakouf372b812023-02-14 18:06:51 -08002321 }
2322
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002323 if (isDown && tempTouchState.hasHoveringPointers(entry.deviceId)) {
2324 // Compatibility behaviour: ACTION_DOWN causes HOVER_EXIT to get generated.
2325 tempTouchState.clearHoveringPointers(entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002326 }
2327
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002328 if (isHoverAction) {
Siarhei Vishniakou7be50c92023-11-17 17:09:08 -08002329 if (wasDown) {
2330 // Started hovering, but the device is already down: reject the hover event
2331 LOG(ERROR) << "Got hover event " << entry.getDescription()
2332 << " but the device is already down " << oldState->dump();
2333 outInjectionResult = InputEventInjectionResult::FAILED;
2334 return {};
2335 }
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002336 // For hover actions, we will treat 'tempTouchState' as a new state, so let's erase
2337 // all of the existing hovering pointers and recompute.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002338 tempTouchState.clearHoveringPointers(entry.deviceId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002339 }
2340
Michael Wrightd02c5b62014-02-10 15:10:22 -08002341 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2342 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07002343 const auto [x, y] = resolveTouchedPosition(entry);
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002344 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002345 const PointerProperties& pointer = entry.pointerProperties[pointerIndex];
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002346 // Outside targets should be added upon first dispatched DOWN event. That means, this should
2347 // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down.
Prabir Pradhand65552b2021-10-07 11:23:50 -07002348 const bool isStylus = isPointerFromStylus(entry, pointerIndex);
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002349 sp<WindowInfoHandle> newTouchedWindowHandle =
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002350 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Michael Wright3dd60e22019-03-27 22:06:44 +00002351
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002352 if (isDown) {
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002353 targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointer.id);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002354 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002355 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002356 if (newTouchedWindowHandle == nullptr) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00002357 ALOGD("No new touched window at (%.1f, %.1f) in display %" PRId32, x, y, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002358 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002359 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002360 }
2361
Prabir Pradhan5735a322022-04-11 17:23:34 +00002362 // Verify targeted injection.
2363 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2364 ALOGW("Dropping injected touch event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002365 outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
Prabir Pradhan5735a322022-04-11 17:23:34 +00002366 newTouchedWindowHandle = nullptr;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002367 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002368 }
2369
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002370 // Figure out whether splitting will be allowed for this window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002371 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002372 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2373 // New window supports splitting, but we should never split mouse events.
2374 isSplit = !isFromMouse;
2375 } else if (isSplit) {
2376 // New window does not support splitting but we have already split events.
2377 // Ignore the new window.
Siarhei Vishniakou25537f82023-07-18 14:35:47 -07002378 LOG(INFO) << "Skipping " << newTouchedWindowHandle->getName()
2379 << " because it doesn't support split touch";
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002380 newTouchedWindowHandle = nullptr;
2381 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002382 } else {
2383 // No window is touched, so set split to true. This will allow the next pointer down to
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002384 // be delivered to a new window which supports split touch. Pointers from a mouse device
2385 // should never be split.
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002386 isSplit = !isFromMouse;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002387 }
2388
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002389 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002390 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002391 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002392 // Process the foreground window first so that it is the first to receive the event.
2393 newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002394 }
2395
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002396 if (newTouchedWindows.empty()) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00002397 ALOGI("Dropping event because there is no touchable window at (%.1f, %.1f) on display "
2398 "%d.",
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002399 x, y, displayId);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002400 outInjectionResult = InputEventInjectionResult::FAILED;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002401 return {};
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002402 }
2403
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002404 for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07002405 if (!canWindowReceiveMotionLocked(windowHandle, entry)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002406 continue;
2407 }
2408
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002409 if (isHoverAction) {
Siarhei Vishniakoub681c202023-05-01 11:22:33 -07002410 // The "windowHandle" is the target of this hovering pointer.
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002411 tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointer);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002412 }
2413
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002414 // Set target flags.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002415 ftl::Flags<InputTarget::Flags> targetFlags;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002416
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002417 if (canReceiveForegroundTouches(*windowHandle->getInfo())) {
2418 // There should only be one touched window that can be "foreground" for the pointer.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002419 targetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002420 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002421
2422 if (isSplit) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002423 targetFlags |= InputTarget::Flags::SPLIT;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002424 }
2425 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002426 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002427 } else if (isWindowObscuredLocked(windowHandle)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002428 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002429 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002430
2431 // Update the temporary touch state.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002432
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002433 if (!isHoverAction) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002434 const bool isDownOrPointerDown = maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2435 maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002436 tempTouchState.addOrUpdateWindow(windowHandle, InputTarget::DispatchMode::AS_IS,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002437 targetFlags, entry.deviceId, {pointer},
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002438 isDownOrPointerDown
2439 ? std::make_optional(entry.eventTime)
2440 : std::nullopt);
2441 // If this is the pointer going down and the touched window has a wallpaper
2442 // then also add the touched wallpaper windows so they are locked in for the
2443 // duration of the touch gesture. We do not collect wallpapers during HOVER_MOVE or
2444 // SCROLL because the wallpaper engine only supports touch events. We would need to
2445 // add a mechanism similar to View.onGenericMotionEvent to enable wallpapers to
2446 // handle these events.
2447 if (isDownOrPointerDown && targetFlags.test(InputTarget::Flags::FOREGROUND) &&
Arthur Hungc539dbb2022-12-08 07:45:36 +00002448 windowHandle->getInfo()->inputConfig.test(
2449 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
2450 sp<WindowInfoHandle> wallpaper = findWallpaperWindowBelow(windowHandle);
2451 if (wallpaper != nullptr) {
2452 ftl::Flags<InputTarget::Flags> wallpaperFlags =
2453 InputTarget::Flags::WINDOW_IS_OBSCURED |
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002454 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Arthur Hungc539dbb2022-12-08 07:45:36 +00002455 if (isSplit) {
2456 wallpaperFlags |= InputTarget::Flags::SPLIT;
2457 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002458 tempTouchState.addOrUpdateWindow(wallpaper,
2459 InputTarget::DispatchMode::AS_IS,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002460 wallpaperFlags, entry.deviceId, {pointer},
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002461 entry.eventTime);
Arthur Hungc539dbb2022-12-08 07:45:36 +00002462 }
2463 }
2464 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002465 }
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00002466
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002467 // If a window is already pilfering some pointers, give it this new pointer as well and
2468 // make it pilfering. This will prevent other non-spy windows from getting this pointer,
2469 // which is a specific behaviour that we want.
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002470 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002471 if (touchedWindow.hasTouchingPointer(entry.deviceId, pointer.id) &&
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002472 touchedWindow.hasPilferingPointers(entry.deviceId)) {
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002473 // This window is already pilfering some pointers, and this new pointer is also
2474 // going to it. Therefore, take over this pointer and don't give it to anyone
2475 // else.
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002476 touchedWindow.addPilferingPointer(entry.deviceId, pointer.id);
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00002477 }
2478 }
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002479
2480 // Restrict all pilfered pointers to the pilfering windows.
2481 tempTouchState.cancelPointersForNonPilferingWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002482 } else {
2483 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2484
2485 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002486 if (!tempTouchState.isDown(entry.deviceId) &&
2487 maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) {
Siarhei Vishniakou31dd1552023-10-30 18:46:10 -07002488 if (DEBUG_DROPPED_EVENTS_VERBOSE) {
2489 LOG(INFO) << "Dropping event because the pointer for device " << entry.deviceId
2490 << " is not down or we previously dropped the pointer down event in "
2491 << "display " << displayId << ": " << entry.getDescription();
2492 }
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002493 outInjectionResult = InputEventInjectionResult::FAILED;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002494 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002495 }
2496
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002497 // If the pointer is not currently hovering, then ignore the event.
2498 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2499 const int32_t pointerId = entry.pointerProperties[0].id;
2500 if (oldState == nullptr ||
2501 oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId).empty()) {
2502 LOG(INFO) << "Dropping event because the hovering pointer is not in any windows in "
2503 "display "
2504 << displayId << ": " << entry.getDescription();
2505 outInjectionResult = InputEventInjectionResult::FAILED;
2506 return {};
2507 }
2508 tempTouchState.removeHoveringPointer(entry.deviceId, pointerId);
2509 }
2510
arthurhung6d4bed92021-03-17 11:59:33 +08002511 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002512
Michael Wrightd02c5b62014-02-10 15:10:22 -08002513 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002514 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.getPointerCount() == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002515 tempTouchState.isSlippery()) {
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07002516 const auto [x, y] = resolveTouchedPosition(entry);
Harry Cutts33476232023-01-30 19:57:29 +00002517 const bool isStylus = isPointerFromStylus(entry, /*pointerIndex=*/0);
chaviw98318de2021-05-19 16:45:23 -05002518 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002519 tempTouchState.getFirstForegroundWindowHandle();
Siarhei Vishniakou0f6558d2023-04-21 12:05:13 -07002520 LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr);
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002521 sp<WindowInfoHandle> newTouchedWindowHandle =
2522 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Vishnu Nair062a8672021-09-03 16:07:44 -07002523
Prabir Pradhan5735a322022-04-11 17:23:34 +00002524 // Verify targeted injection.
2525 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2526 ALOGW("Dropping injected event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002527 outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002528 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002529 }
2530
Vishnu Nair062a8672021-09-03 16:07:44 -07002531 // Drop touch events if requested by input feature
2532 if (newTouchedWindowHandle != nullptr &&
2533 shouldDropInput(entry, newTouchedWindowHandle)) {
2534 newTouchedWindowHandle = nullptr;
2535 }
2536
Siarhei Vishniakouafa08cc2023-05-08 22:35:50 -07002537 if (newTouchedWindowHandle != nullptr &&
2538 !haveSameToken(oldTouchedWindowHandle, newTouchedWindowHandle)) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002539 ALOGI("Touch is slipping out of window %s into window %s in display %" PRId32,
Siarhei Vishniakou0f6558d2023-04-21 12:05:13 -07002540 oldTouchedWindowHandle->getName().c_str(),
2541 newTouchedWindowHandle->getName().c_str(), displayId);
2542
Michael Wrightd02c5b62014-02-10 15:10:22 -08002543 // Make a slippery exit from the old window.
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08002544 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002545 const PointerProperties& pointer = entry.pointerProperties[0];
2546 pointerIds.set(pointer.id);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002547
2548 const TouchedWindow& touchedWindow =
2549 tempTouchState.getTouchedWindow(oldTouchedWindowHandle);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002550 addPointerWindowTargetLocked(oldTouchedWindowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002551 InputTarget::DispatchMode::SLIPPERY_EXIT,
2552 ftl::Flags<InputTarget::Flags>(), pointerIds,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002553 touchedWindow.getDownTimeInTarget(entry.deviceId),
2554 targets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002555
2556 // Make a slippery entrance into the new window.
2557 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002558 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002559 }
2560
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002561 ftl::Flags<InputTarget::Flags> targetFlags;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002562 if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002563 targetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002564 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002565 if (isSplit) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002566 targetFlags |= InputTarget::Flags::SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002567 }
2568 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002569 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002570 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002571 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002572 }
2573
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002574 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle,
2575 InputTarget::DispatchMode::SLIPPERY_ENTER,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002576 targetFlags, entry.deviceId, {pointer},
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002577 entry.eventTime);
Arthur Hungc539dbb2022-12-08 07:45:36 +00002578
2579 // Check if the wallpaper window should deliver the corresponding event.
2580 slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002581 tempTouchState, entry.deviceId, pointer, targets);
2582 tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointer.id,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002583 oldTouchedWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002584 }
2585 }
Arthur Hung96483742022-11-15 03:30:48 +00002586
2587 // Update the pointerIds for non-splittable when it received pointer down.
2588 if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2589 // If no split, we suppose all touched windows should receive pointer down.
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002590 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002591 std::vector<PointerProperties> touchingPointers{entry.pointerProperties[pointerIndex]};
2592 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
Arthur Hung96483742022-11-15 03:30:48 +00002593 // Ignore drag window for it should just track one pointer.
2594 if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
2595 continue;
2596 }
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002597 touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers);
Arthur Hung96483742022-11-15 03:30:48 +00002598 }
2599 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002600 }
2601
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002602 // Update dispatching for hover enter and exit.
Sam Dubeyf886dec2023-01-27 13:28:19 +00002603 {
2604 std::vector<TouchedWindow> hoveringWindows =
2605 getHoveringWindowsLocked(oldState, tempTouchState, entry);
2606 for (const TouchedWindow& touchedWindow : hoveringWindows) {
Siarhei Vishniakoud5876ba2023-05-15 17:58:34 -07002607 std::optional<InputTarget> target =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002608 createInputTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
2609 touchedWindow.targetFlags,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002610 touchedWindow.getDownTimeInTarget(entry.deviceId));
Siarhei Vishniakoud5876ba2023-05-15 17:58:34 -07002611 if (!target) {
2612 continue;
2613 }
2614 // Hardcode to single hovering pointer for now.
2615 std::bitset<MAX_POINTER_ID + 1> pointerIds;
2616 pointerIds.set(entry.pointerProperties[0].id);
2617 target->addPointers(pointerIds, touchedWindow.windowHandle->getInfo()->transform);
2618 targets.push_back(*target);
Sam Dubeyf886dec2023-01-27 13:28:19 +00002619 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002620 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002621
Prabir Pradhan5735a322022-04-11 17:23:34 +00002622 // Ensure that all touched windows are valid for injection.
2623 if (entry.injectionState != nullptr) {
2624 std::string errs;
2625 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Prabir Pradhan5735a322022-04-11 17:23:34 +00002626 const auto err = verifyTargetedInjection(touchedWindow.windowHandle, entry);
2627 if (err) errs += "\n - " + *err;
2628 }
2629 if (!errs.empty()) {
2630 ALOGW("Dropping targeted injection: At least one touched window is not owned by uid "
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00002631 "%s:%s",
2632 entry.injectionState->targetUid->toString().c_str(), errs.c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002633 outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002634 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002635 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002636 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002637
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002638 // Check whether windows listening for outside touches are owned by the same UID. If the owner
2639 // has a different UID, then we will not reveal coordinate information to this window.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002640 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002641 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002642 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002643 if (foregroundWindowHandle) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00002644 const auto foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002645 for (InputTarget& target : targets) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002646 if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002647 sp<WindowInfoHandle> targetWindow =
2648 getWindowHandleLocked(target.inputChannel->getConnectionToken());
2649 if (targetWindow->getInfo()->ownerUid != foregroundWindowUid) {
2650 target.flags |= InputTarget::Flags::ZERO_COORDS;
Michael Wright3dd60e22019-03-27 22:06:44 +00002651 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002652 }
2653 }
2654 }
2655 }
2656
Harry Cuttsb166c002023-05-09 13:06:05 +00002657 // If this is a touchpad navigation gesture, it needs to only be sent to trusted targets, as we
2658 // only want the system UI to handle these gestures.
2659 const bool isTouchpadNavGesture = isFromSource(entry.source, AINPUT_SOURCE_MOUSE) &&
2660 entry.classification == MotionClassification::MULTI_FINGER_SWIPE;
2661 if (isTouchpadNavGesture) {
2662 filterUntrustedTargets(/* byref */ tempTouchState, /* byref */ targets);
2663 }
2664
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002665 // Output targets from the touch state.
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002666 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002667 std::vector<PointerProperties> touchingPointers =
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002668 touchedWindow.getTouchingPointers(entry.deviceId);
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002669 if (touchingPointers.empty()) {
Siarhei Vishniakoue0431e42023-01-28 17:01:39 -08002670 continue;
2671 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002672 addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08002673 touchedWindow.targetFlags, getPointerIds(touchingPointers),
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002674 touchedWindow.getDownTimeInTarget(entry.deviceId), targets);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002675 }
Sam Dubey39d37cf2022-12-07 18:05:35 +00002676
Siarhei Vishniakou580fb3a2023-05-05 15:02:20 -07002677 // During targeted injection, only allow owned targets to receive events
2678 std::erase_if(targets, [&](const InputTarget& target) {
2679 LOG_ALWAYS_FATAL_IF(target.windowHandle == nullptr);
2680 const auto err = verifyTargetedInjection(target.windowHandle, entry);
2681 if (err) {
2682 LOG(WARNING) << "Dropping injected event from " << target.windowHandle->getName()
2683 << ": " << (*err);
2684 return true;
2685 }
2686 return false;
2687 });
2688
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002689 if (targets.empty()) {
2690 LOG(INFO) << "Dropping event because no targets were found: " << entry.getDescription();
2691 outInjectionResult = InputEventInjectionResult::FAILED;
2692 return {};
2693 }
2694
2695 // If we only have windows getting ACTION_OUTSIDE, then drop the event, because there is no
2696 // window that is actually receiving the entire gesture.
2697 if (std::all_of(targets.begin(), targets.end(), [](const InputTarget& target) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002698 return target.dispatchMode == InputTarget::DispatchMode::OUTSIDE;
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002699 })) {
2700 LOG(INFO) << "Dropping event because all windows would just receive ACTION_OUTSIDE: "
2701 << entry.getDescription();
2702 outInjectionResult = InputEventInjectionResult::FAILED;
2703 return {};
2704 }
2705
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002706 outInjectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002707
Prabir Pradhan502a7252023-12-01 16:11:24 +00002708 // Now that we have generated all of the input targets for this event, reset the dispatch
2709 // mode for all touched window to AS_IS.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002710 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
Prabir Pradhan502a7252023-12-01 16:11:24 +00002711 touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002712 }
2713
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002714 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou7be50c92023-11-17 17:09:08 -08002715 if (maskedAction == AMOTION_EVENT_ACTION_UP) {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002716 // Pointer went up.
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002717 tempTouchState.removeTouchingPointer(entry.deviceId, entry.pointerProperties[0].id);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002718 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002719 // All pointers up or canceled.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002720 tempTouchState.removeAllPointersForDevice(entry.deviceId);
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002721 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2722 // One pointer went up.
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002723 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
2724 const uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
2725 tempTouchState.removeTouchingPointer(entry.deviceId, pointerId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002726 }
2727
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002728 // Save changes unless the action was scroll in which case the temporary touch
2729 // state was only valid for this one action.
2730 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07002731 if (displayId >= 0) {
Siarhei Vishniakouf372b812023-02-14 18:06:51 -08002732 tempTouchState.clearWindowsWithoutPointers();
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002733 mTouchStatesByDisplay[displayId] = tempTouchState;
2734 } else {
2735 mTouchStatesByDisplay.erase(displayId);
2736 }
2737 }
2738
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08002739 if (tempTouchState.windows.empty()) {
2740 mTouchStatesByDisplay.erase(displayId);
2741 }
2742
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002743 return targets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002744}
2745
arthurhung6d4bed92021-03-17 11:59:33 +08002746void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07002747 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2748 // have an explicit reason to support it.
2749 constexpr bool isStylus = false;
2750
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002751 sp<WindowInfoHandle> dropWindow =
Harry Cutts33476232023-01-30 19:57:29 +00002752 findTouchedWindowAtLocked(displayId, x, y, isStylus, /*ignoreDragWindow=*/true);
arthurhung6d4bed92021-03-17 11:59:33 +08002753 if (dropWindow) {
2754 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002755 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002756 } else {
Arthur Hung54745652022-04-20 07:17:41 +00002757 ALOGW("No window found when drop.");
Prabir Pradhancef936d2021-07-21 16:17:52 +00002758 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002759 }
2760 mDragState.reset();
2761}
2762
2763void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
Arthur Hung3915c1f2022-05-31 07:17:17 +00002764 if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId) {
arthurhungb89ccb02020-12-30 16:19:01 +08002765 return;
2766 }
2767
arthurhung6d4bed92021-03-17 11:59:33 +08002768 if (!mDragState->isStartDrag) {
2769 mDragState->isStartDrag = true;
2770 mDragState->isStylusButtonDownAtStart =
2771 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2772 }
2773
Arthur Hung54745652022-04-20 07:17:41 +00002774 // Find the pointer index by id.
2775 int32_t pointerIndex = 0;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002776 for (; static_cast<uint32_t>(pointerIndex) < entry.getPointerCount(); pointerIndex++) {
Arthur Hung54745652022-04-20 07:17:41 +00002777 const PointerProperties& pointerProperties = entry.pointerProperties[pointerIndex];
2778 if (pointerProperties.id == mDragState->pointerId) {
2779 break;
arthurhung6d4bed92021-03-17 11:59:33 +08002780 }
Arthur Hung54745652022-04-20 07:17:41 +00002781 }
arthurhung6d4bed92021-03-17 11:59:33 +08002782
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002783 if (uint32_t(pointerIndex) == entry.getPointerCount()) {
Arthur Hung54745652022-04-20 07:17:41 +00002784 LOG_ALWAYS_FATAL("Should find a valid pointer index by id %d", mDragState->pointerId);
Arthur Hung54745652022-04-20 07:17:41 +00002785 }
2786
2787 const int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2788 const int32_t x = entry.pointerCoords[pointerIndex].getX();
2789 const int32_t y = entry.pointerCoords[pointerIndex].getY();
2790
2791 switch (maskedAction) {
2792 case AMOTION_EVENT_ACTION_MOVE: {
2793 // Handle the special case : stylus button no longer pressed.
2794 bool isStylusButtonDown =
2795 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2796 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2797 finishDragAndDrop(entry.displayId, x, y);
2798 return;
2799 }
2800
2801 // Prevent stylus interceptor windows from affecting drag and drop behavior for now,
2802 // until we have an explicit reason to support it.
2803 constexpr bool isStylus = false;
2804
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002805 sp<WindowInfoHandle> hoverWindowHandle =
2806 findTouchedWindowAtLocked(entry.displayId, x, y, isStylus,
2807 /*ignoreDragWindow=*/true);
Arthur Hung54745652022-04-20 07:17:41 +00002808 // enqueue drag exit if needed.
2809 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2810 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2811 if (mDragState->dragHoverWindowHandle != nullptr) {
Harry Cutts33476232023-01-30 19:57:29 +00002812 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, /*isExiting=*/true, x,
Arthur Hung54745652022-04-20 07:17:41 +00002813 y);
2814 }
2815 mDragState->dragHoverWindowHandle = hoverWindowHandle;
2816 }
2817 // enqueue drag location if needed.
2818 if (hoverWindowHandle != nullptr) {
Harry Cutts33476232023-01-30 19:57:29 +00002819 enqueueDragEventLocked(hoverWindowHandle, /*isExiting=*/false, x, y);
Arthur Hung54745652022-04-20 07:17:41 +00002820 }
2821 break;
2822 }
2823
2824 case AMOTION_EVENT_ACTION_POINTER_UP:
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002825 if (MotionEvent::getActionIndex(entry.action) != pointerIndex) {
Arthur Hung54745652022-04-20 07:17:41 +00002826 break;
2827 }
2828 // The drag pointer is up.
2829 [[fallthrough]];
2830 case AMOTION_EVENT_ACTION_UP:
2831 finishDragAndDrop(entry.displayId, x, y);
2832 break;
2833 case AMOTION_EVENT_ACTION_CANCEL: {
2834 ALOGD("Receiving cancel when drag and drop.");
2835 sendDropWindowCommandLocked(nullptr, 0, 0);
2836 mDragState.reset();
2837 break;
2838 }
arthurhungb89ccb02020-12-30 16:19:01 +08002839 }
2840}
2841
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002842std::optional<InputTarget> InputDispatcher::createInputTargetLocked(
2843 const sp<android::gui::WindowInfoHandle>& windowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002844 InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002845 std::optional<nsecs_t> firstDownTimeInTarget) const {
2846 std::shared_ptr<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
2847 if (inputChannel == nullptr) {
2848 ALOGW("Not creating InputTarget for %s, no input channel", windowHandle->getName().c_str());
2849 return {};
2850 }
2851 InputTarget inputTarget;
2852 inputTarget.inputChannel = inputChannel;
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00002853 inputTarget.windowHandle = windowHandle;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002854 inputTarget.dispatchMode = dispatchMode;
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002855 inputTarget.flags = targetFlags;
2856 inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor;
2857 inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
2858 const auto& displayInfoIt = mDisplayInfos.find(windowHandle->getInfo()->displayId);
2859 if (displayInfoIt != mDisplayInfos.end()) {
2860 inputTarget.displayTransform = displayInfoIt->second.transform;
2861 } else {
Siarhei Vishniakou580fb3a2023-05-05 15:02:20 -07002862 // DisplayInfo not found for this window on display windowHandle->getInfo()->displayId.
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002863 // TODO(b/198444055): Make this an error message after 'setInputWindows' API is removed.
2864 }
2865 return inputTarget;
2866}
2867
chaviw98318de2021-05-19 16:45:23 -05002868void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002869 InputTarget::DispatchMode dispatchMode,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002870 ftl::Flags<InputTarget::Flags> targetFlags,
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002871 std::optional<nsecs_t> firstDownTimeInTarget,
Siarhei Vishniakouf75cddb2022-10-25 10:42:16 -07002872 std::vector<InputTarget>& inputTargets) const {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002873 std::vector<InputTarget>::iterator it =
2874 std::find_if(inputTargets.begin(), inputTargets.end(),
2875 [&windowHandle](const InputTarget& inputTarget) {
2876 return inputTarget.inputChannel->getConnectionToken() ==
2877 windowHandle->getToken();
2878 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002879
chaviw98318de2021-05-19 16:45:23 -05002880 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002881
2882 if (it == inputTargets.end()) {
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002883 std::optional<InputTarget> target =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002884 createInputTargetLocked(windowHandle, dispatchMode, targetFlags,
2885 firstDownTimeInTarget);
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002886 if (!target) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002887 return;
2888 }
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002889 inputTargets.push_back(*target);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002890 it = inputTargets.end() - 1;
2891 }
2892
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002893 if (it->flags != targetFlags) {
2894 LOG(ERROR) << "Flags don't match! targetFlags=" << targetFlags.string() << ", it=" << *it;
2895 }
2896 if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
2897 LOG(ERROR) << "Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
2898 << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
2899 }
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002900}
2901
2902void InputDispatcher::addPointerWindowTargetLocked(
2903 const sp<android::gui::WindowInfoHandle>& windowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002904 InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
2905 std::bitset<MAX_POINTER_ID + 1> pointerIds, std::optional<nsecs_t> firstDownTimeInTarget,
2906 std::vector<InputTarget>& inputTargets) const REQUIRES(mLock) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002907 if (pointerIds.none()) {
2908 for (const auto& target : inputTargets) {
2909 LOG(INFO) << "Target: " << target;
2910 }
2911 LOG(FATAL) << "No pointers specified for " << windowHandle->getName();
2912 return;
2913 }
2914 std::vector<InputTarget>::iterator it =
2915 std::find_if(inputTargets.begin(), inputTargets.end(),
2916 [&windowHandle](const InputTarget& inputTarget) {
2917 return inputTarget.inputChannel->getConnectionToken() ==
2918 windowHandle->getToken();
2919 });
2920
2921 // This is a hack, because the actual entry could potentially be an ACTION_DOWN event that
2922 // causes a HOVER_EXIT to be generated. That means that the same entry of ACTION_DOWN would
2923 // have DISPATCH_AS_HOVER_EXIT and DISPATCH_AS_IS. And therefore, we have to create separate
2924 // input targets for hovering pointers and for touching pointers.
2925 // If we picked an existing input target above, but it's for HOVER_EXIT - let's use a new
2926 // target instead.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002927 if (it != inputTargets.end() && it->dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002928 // Force the code below to create a new input target
2929 it = inputTargets.end();
2930 }
2931
2932 const WindowInfo* windowInfo = windowHandle->getInfo();
2933
2934 if (it == inputTargets.end()) {
2935 std::optional<InputTarget> target =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002936 createInputTargetLocked(windowHandle, dispatchMode, targetFlags,
2937 firstDownTimeInTarget);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002938 if (!target) {
2939 return;
2940 }
2941 inputTargets.push_back(*target);
2942 it = inputTargets.end() - 1;
2943 }
2944
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002945 if (it->dispatchMode != dispatchMode) {
2946 LOG(ERROR) << __func__ << ": DispatchMode doesn't match! ignoring new mode="
2947 << ftl::enum_string(dispatchMode) << ", it=" << *it;
2948 }
Siarhei Vishniakou4bd0b7c2023-10-27 00:51:14 -07002949 if (it->flags != targetFlags) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002950 LOG(ERROR) << __func__ << ": Flags don't match! new targetFlags=" << targetFlags.string()
2951 << ", it=" << *it;
Siarhei Vishniakou4bd0b7c2023-10-27 00:51:14 -07002952 }
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002953 if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002954 LOG(ERROR) << __func__ << ": Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002955 << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
2956 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002957
chaviw1ff3d1e2020-07-01 15:53:47 -07002958 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002959}
2960
Michael Wright3dd60e22019-03-27 22:06:44 +00002961void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002962 int32_t displayId) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002963 auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
2964 if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
Michael Wright3dd60e22019-03-27 22:06:44 +00002965
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002966 for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
2967 InputTarget target;
2968 target.inputChannel = monitor.inputChannel;
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002969 // target.firstDownTimeInTarget is not set for global monitors. It is only required in split
2970 // touch and global monitoring works as intended even without setting firstDownTimeInTarget
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002971 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
2972 target.displayTransform = it->second.transform;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002973 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002974 target.setDefaultPointerTransform(target.displayTransform);
2975 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002976 }
2977}
2978
Robert Carrc9bf1d32020-04-13 17:21:08 -07002979/**
2980 * Indicate whether one window handle should be considered as obscuring
2981 * another window handle. We only check a few preconditions. Actually
2982 * checking the bounds is left to the caller.
2983 */
chaviw98318de2021-05-19 16:45:23 -05002984static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2985 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002986 // Compare by token so cloned layers aren't counted
2987 if (haveSameToken(windowHandle, otherHandle)) {
2988 return false;
2989 }
2990 auto info = windowHandle->getInfo();
2991 auto otherInfo = otherHandle->getInfo();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002992 if (otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002993 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002994 } else if (otherInfo->alpha == 0 &&
2995 otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002996 // Those act as if they were invisible, so we don't need to flag them.
2997 // We do want to potentially flag touchable windows even if they have 0
2998 // opacity, since they can consume touches and alter the effects of the
2999 // user interaction (eg. apps that rely on
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003000 // Flags::WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
Bernardo Rufino653d2e02020-10-20 17:32:40 +00003001 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
3002 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00003003 } else if (info->ownerUid == otherInfo->ownerUid) {
3004 // If ownerUid is the same we don't generate occlusion events as there
3005 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07003006 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08003007 } else if (otherInfo->inputConfig.test(gui::WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07003008 return false;
3009 } else if (otherInfo->displayId != info->displayId) {
3010 return false;
3011 }
3012 return true;
3013}
3014
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003015/**
3016 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
3017 * untrusted, one should check:
3018 *
3019 * 1. If result.hasBlockingOcclusion is true.
3020 * If it's, it means the touch should be blocked due to a window with occlusion mode of
3021 * BLOCK_UNTRUSTED.
3022 *
3023 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
3024 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
3025 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
3026 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
3027 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
3028 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
3029 *
3030 * If neither of those is true, then it means the touch can be allowed.
3031 */
3032InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05003033 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
3034 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003035 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05003036 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003037 TouchOcclusionInfo info;
3038 info.hasBlockingOcclusion = false;
3039 info.obscuringOpacity = 0;
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003040 info.obscuringUid = gui::Uid::INVALID;
3041 std::map<gui::Uid, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05003042 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003043 if (windowHandle == otherHandle) {
3044 break; // All future windows are below us. Exit early.
3045 }
chaviw98318de2021-05-19 16:45:23 -05003046 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00003047 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
3048 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003049 if (DEBUG_TOUCH_OCCLUSION) {
3050 info.debugInfo.push_back(
Harry Cutts101ee9b2023-07-06 18:04:14 +00003051 dumpWindowForTouchOcclusion(otherInfo, /*isTouchedWindow=*/false));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003052 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003053 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
3054 // we perform the checks below to see if the touch can be propagated or not based on the
3055 // window's touch occlusion mode
3056 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
3057 info.hasBlockingOcclusion = true;
3058 info.obscuringUid = otherInfo->ownerUid;
3059 info.obscuringPackage = otherInfo->packageName;
3060 break;
3061 }
3062 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003063 const auto uid = otherInfo->ownerUid;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003064 float opacity =
3065 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
3066 // Given windows A and B:
3067 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
3068 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
3069 opacityByUid[uid] = opacity;
3070 if (opacity > info.obscuringOpacity) {
3071 info.obscuringOpacity = opacity;
3072 info.obscuringUid = uid;
3073 info.obscuringPackage = otherInfo->packageName;
3074 }
3075 }
3076 }
3077 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003078 if (DEBUG_TOUCH_OCCLUSION) {
Harry Cutts101ee9b2023-07-06 18:04:14 +00003079 info.debugInfo.push_back(dumpWindowForTouchOcclusion(windowInfo, /*isTouchedWindow=*/true));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003080 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003081 return info;
3082}
3083
chaviw98318de2021-05-19 16:45:23 -05003084std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003085 bool isTouchedWindow) const {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003086 return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
Prabir Pradhan51e7db02022-02-07 06:02:57 -08003087 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
3088 "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
3089 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08003090 isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003091 info->ownerUid.toString().c_str(), info->id,
Chavi Weingarten7f019192023-08-08 20:39:01 +00003092 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frame.left,
3093 info->frame.top, info->frame.right, info->frame.bottom,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003094 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
3095 info->inputConfig.string().c_str(), toString(info->token != nullptr),
3096 info->applicationInfo.name.c_str(),
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07003097 binderToString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003098}
3099
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003100bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
3101 if (occlusionInfo.hasBlockingOcclusion) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003102 ALOGW("Untrusted touch due to occlusion by %s/%s", occlusionInfo.obscuringPackage.c_str(),
3103 occlusionInfo.obscuringUid.toString().c_str());
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003104 return false;
3105 }
3106 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003107 ALOGW("Untrusted touch due to occlusion by %s/%s (obscuring opacity = "
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003108 "%.2f, maximum allowed = %.2f)",
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003109 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid.toString().c_str(),
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003110 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
3111 return false;
3112 }
3113 return true;
3114}
3115
chaviw98318de2021-05-19 16:45:23 -05003116bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003117 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003118 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05003119 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3120 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07003121 if (windowHandle == otherHandle) {
3122 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08003123 }
chaviw98318de2021-05-19 16:45:23 -05003124 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07003125 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08003126 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003127 return true;
3128 }
3129 }
3130 return false;
3131}
3132
chaviw98318de2021-05-19 16:45:23 -05003133bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003134 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05003135 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3136 const WindowInfo* windowInfo = windowHandle->getInfo();
3137 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07003138 if (windowHandle == otherHandle) {
3139 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003140 }
chaviw98318de2021-05-19 16:45:23 -05003141 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07003142 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08003143 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003144 return true;
3145 }
3146 }
3147 return false;
3148}
3149
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003150std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05003151 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003152 if (applicationHandle != nullptr) {
3153 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07003154 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003155 } else {
3156 return applicationHandle->getName();
3157 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003158 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07003159 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003160 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003161 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003162 }
3163}
3164
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003165void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00003166 if (!isUserActivityEvent(eventEntry)) {
3167 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003168 return;
3169 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003170 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05003171 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Josep del Riob3981622023-04-18 15:49:45 +00003172 const WindowInfo* windowDisablingUserActivityInfo = nullptr;
Tiger Huang721e26f2018-07-24 22:26:19 +08003173 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003174 const WindowInfo* info = focusedWindowHandle->getInfo();
Prabir Pradhan51e7db02022-02-07 06:02:57 -08003175 if (info->inputConfig.test(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY)) {
Josep del Riob3981622023-04-18 15:49:45 +00003176 windowDisablingUserActivityInfo = info;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003177 }
3178 }
3179
3180 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003181 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003182 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003183 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3184 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003185 return;
3186 }
Josep del Riob3981622023-04-18 15:49:45 +00003187 if (windowDisablingUserActivityInfo != nullptr) {
3188 if (DEBUG_DISPATCH_CYCLE) {
3189 ALOGD("Not poking user activity: disabled by window '%s'.",
3190 windowDisablingUserActivityInfo->name.c_str());
3191 }
3192 return;
3193 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003194 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003195 eventType = USER_ACTIVITY_EVENT_TOUCH;
3196 }
3197 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003198 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003199 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003200 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3201 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003202 return;
3203 }
Josep del Riob3981622023-04-18 15:49:45 +00003204 // If the key code is unknown, we don't consider it user activity
3205 if (keyEntry.keyCode == AKEYCODE_UNKNOWN) {
3206 return;
3207 }
3208 // Don't inhibit events that were intercepted or are not passed to
3209 // the apps, like system shortcuts
3210 if (windowDisablingUserActivityInfo != nullptr &&
3211 keyEntry.interceptKeyResult != KeyEntry::InterceptKeyResult::SKIP &&
3212 keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER) {
3213 if (DEBUG_DISPATCH_CYCLE) {
3214 ALOGD("Not poking user activity: disabled by window '%s'.",
3215 windowDisablingUserActivityInfo->name.c_str());
3216 }
3217 return;
3218 }
3219
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003220 eventType = USER_ACTIVITY_EVENT_BUTTON;
3221 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003222 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00003223 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003224 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08003225 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003226 break;
3227 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003228 }
3229
Prabir Pradhancef936d2021-07-21 16:17:52 +00003230 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
3231 REQUIRES(mLock) {
3232 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003233 mPolicy.pokeUserActivity(eventTime, eventType, displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00003234 };
3235 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003236}
3237
3238void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003239 const std::shared_ptr<Connection>& connection,
Prabir Pradhan24047542023-11-02 17:14:59 +00003240 std::shared_ptr<const EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003241 const InputTarget& inputTarget) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003242 ATRACE_NAME_IF(ATRACE_ENABLED(),
3243 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
3244 connection->getInputChannelName().c_str(), eventEntry->id));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003245 if (DEBUG_DISPATCH_CYCLE) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003246 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=%s, "
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08003247 "globalScaleFactor=%f, pointerIds=%s %s",
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003248 connection->getInputChannelName().c_str(), inputTarget.flags.string().c_str(),
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08003249 inputTarget.globalScaleFactor, bitsetToString(inputTarget.pointerIds).c_str(),
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003250 inputTarget.getPointerInfoString().c_str());
3251 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003252
3253 // Skip this event if the connection status is not normal.
3254 // We don't want to enqueue additional outbound events if the connection is broken.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003255 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003256 if (DEBUG_DISPATCH_CYCLE) {
3257 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003258 connection->getInputChannelName().c_str(),
3259 ftl::enum_string(connection->status).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003260 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003261 return;
3262 }
3263
3264 // Split a motion event if needed.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003265 if (inputTarget.flags.test(InputTarget::Flags::SPLIT)) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003266 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003267 "Entry type %s should not have Flags::SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08003268 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003269
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003270 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003271 if (inputTarget.pointerIds.count() != originalMotionEntry.getPointerCount()) {
Siarhei Vishniakou16e4fa02023-02-16 17:48:56 -08003272 if (!inputTarget.firstDownTimeInTarget.has_value()) {
3273 logDispatchStateLocked();
3274 LOG(FATAL) << "Splitting motion events requires a down time to be set for the "
3275 "target on connection "
3276 << connection->getInputChannelName() << " for "
3277 << originalMotionEntry.getDescription();
3278 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003279 std::unique_ptr<MotionEntry> splitMotionEntry =
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00003280 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds,
3281 inputTarget.firstDownTimeInTarget.value());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003282 if (!splitMotionEntry) {
3283 return; // split event was dropped
3284 }
Arthur Hungb3307ee2021-10-14 10:57:37 +00003285 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
3286 std::string reason = std::string("reason=pointer cancel on split window");
3287 android_log_event_list(LOGTAG_INPUT_CANCEL)
3288 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3289 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003290 if (DEBUG_FOCUS) {
3291 ALOGD("channel '%s' ~ Split motion event.",
3292 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003293 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003294 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003295 enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection,
3296 std::move(splitMotionEntry),
3297 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003298 return;
3299 }
3300 }
3301
3302 // Not splitting. Enqueue dispatch entries for the event as is.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003303 enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection, eventEntry,
3304 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003305}
3306
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003307void InputDispatcher::enqueueDispatchEntryAndStartDispatchCycleLocked(
3308 nsecs_t currentTime, const std::shared_ptr<Connection>& connection,
3309 std::shared_ptr<const EventEntry> eventEntry, const InputTarget& inputTarget) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003310 ATRACE_NAME_IF(ATRACE_ENABLED(),
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003311 StringPrintf("enqueueDispatchEntryAndStartDispatchCycleLocked(inputChannel=%s, "
3312 "id=0x%" PRIx32 ")",
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003313 connection->getInputChannelName().c_str(), eventEntry->id));
Michael Wright3dd60e22019-03-27 22:06:44 +00003314
hongzuo liu95785e22022-09-06 02:51:35 +00003315 const bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003316
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003317 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318
3319 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003320 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003321 startDispatchCycleLocked(currentTime, connection);
3322 }
3323}
3324
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003325void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,
Prabir Pradhan24047542023-11-02 17:14:59 +00003326 std::shared_ptr<const EventEntry> eventEntry,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003327 const InputTarget& inputTarget) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003328 // This is a new event.
3329 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003330 std::unique_ptr<DispatchEntry> dispatchEntry =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003331 createDispatchEntry(inputTarget, eventEntry, inputTarget.flags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003332
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003333 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
3334 // different EventEntry than what was passed in.
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003335 eventEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003336 // Apply target flags and update the connection's input state.
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003337 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003338 case EventEntry::Type::KEY: {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003339 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*eventEntry);
3340 if (!connection->inputState.trackKey(keyEntry, keyEntry.flags)) {
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -07003341 LOG(WARNING) << "channel " << connection->getInputChannelName()
3342 << "~ dropping inconsistent event: " << *dispatchEntry;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003343 return; // skip the inconsistent event
3344 }
3345 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003346 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003347
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003348 case EventEntry::Type::MOTION: {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003349 std::shared_ptr<const MotionEntry> resolvedMotion =
3350 std::static_pointer_cast<const MotionEntry>(eventEntry);
3351 {
3352 // Determine the resolved motion entry.
3353 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
3354 int32_t resolvedAction = motionEntry.action;
3355 int32_t resolvedFlags = motionEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003356
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003357 if (inputTarget.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003358 resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003359 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003360 resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003361 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_ENTER) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003362 resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003363 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_EXIT) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003364 resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003365 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_ENTER) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003366 resolvedAction = AMOTION_EVENT_ACTION_DOWN;
3367 }
3368 if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
3369 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3370 motionEntry.displayId)) {
3371 if (DEBUG_DISPATCH_CYCLE) {
3372 LOG(DEBUG) << "channel '" << connection->getInputChannelName().c_str()
3373 << "' ~ enqueueDispatchEntryLocked: filling in missing hover "
3374 "enter event";
3375 }
3376 resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3377 }
3378
3379 if (resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
3380 resolvedFlags |= AMOTION_EVENT_FLAG_CANCELED;
3381 }
3382 if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) {
3383 resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3384 }
3385 if (dispatchEntry->targetFlags.test(
3386 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED)) {
3387 resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3388 }
3389
3390 dispatchEntry->resolvedFlags = resolvedFlags;
3391 if (resolvedAction != motionEntry.action) {
3392 // Generate a new MotionEntry with a new eventId using the resolved action and
3393 // flags.
3394 resolvedMotion =
3395 std::make_shared<MotionEntry>(mIdGenerator.nextId(),
3396 motionEntry.injectionState,
3397 motionEntry.eventTime,
3398 motionEntry.deviceId, motionEntry.source,
3399 motionEntry.displayId,
3400 motionEntry.policyFlags, resolvedAction,
3401 motionEntry.actionButton, resolvedFlags,
3402 motionEntry.metaState,
3403 motionEntry.buttonState,
3404 motionEntry.classification,
3405 motionEntry.edgeFlags,
3406 motionEntry.xPrecision,
3407 motionEntry.yPrecision,
3408 motionEntry.xCursorPosition,
3409 motionEntry.yCursorPosition,
3410 motionEntry.downTime,
3411 motionEntry.pointerProperties,
3412 motionEntry.pointerCoords);
3413 if (ATRACE_ENABLED()) {
3414 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3415 ") to MotionEvent(id=0x%" PRIx32 ").",
3416 motionEntry.id, resolvedMotion->id);
3417 ATRACE_NAME(message.c_str());
3418 }
3419
3420 // Set the resolved motion entry in the DispatchEntry.
3421 dispatchEntry->eventEntry = resolvedMotion;
3422 eventEntry = resolvedMotion;
3423 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003424 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003425
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003426 // Check if we need to cancel any of the ongoing gestures. We don't support multiple
3427 // devices being active at the same time in the same window, so if a new device is
3428 // active, cancel the gesture from the old device.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003429 std::unique_ptr<EventEntry> cancelEvent =
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003430 connection->inputState.cancelConflictingInputStream(*resolvedMotion);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003431 if (cancelEvent != nullptr) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003432 LOG(INFO) << "Canceling pointers for device " << resolvedMotion->deviceId << " in "
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003433 << connection->getInputChannelName() << " with event "
3434 << cancelEvent->getDescription();
3435 std::unique_ptr<DispatchEntry> cancelDispatchEntry =
3436 createDispatchEntry(inputTarget, std::move(cancelEvent),
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003437 ftl::Flags<InputTarget::Flags>());
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003438
3439 // Send these cancel events to the queue before sending the event from the new
3440 // device.
3441 connection->outboundQueue.emplace_back(std::move(cancelDispatchEntry));
3442 }
3443
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003444 if (!connection->inputState.trackMotion(*resolvedMotion,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003445 dispatchEntry->resolvedFlags)) {
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -07003446 LOG(WARNING) << "channel " << connection->getInputChannelName()
3447 << "~ dropping inconsistent event: " << *dispatchEntry;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003448 return; // skip the inconsistent event
3449 }
3450
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003451 if ((resolvedMotion->flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3452 (resolvedMotion->policyFlags & POLICY_FLAG_TRUSTED)) {
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003453 // Skip reporting pointer down outside focus to the policy.
3454 break;
3455 }
3456
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003457 dispatchPointerDownOutsideFocus(resolvedMotion->source, resolvedMotion->action,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003458 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003459
3460 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003461 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003462 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003463 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003464 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3465 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003466 break;
3467 }
Chris Yef59a2f42020-10-16 12:55:26 -07003468 case EventEntry::Type::SENSOR: {
3469 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3470 break;
3471 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003472 case EventEntry::Type::CONFIGURATION_CHANGED:
3473 case EventEntry::Type::DEVICE_RESET: {
3474 LOG_ALWAYS_FATAL("%s events should not go to apps",
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003475 ftl::enum_string(eventEntry->type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003476 break;
3477 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003478 }
3479
3480 // Remember that we are waiting for this dispatch to complete.
3481 if (dispatchEntry->hasForegroundTarget()) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003482 incrementPendingForegroundDispatches(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003483 }
3484
3485 // Enqueue the dispatch entry.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003486 connection->outboundQueue.emplace_back(std::move(dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003487 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003488}
3489
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003490/**
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003491 * This function is for debugging and metrics collection. It has two roles.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003492 *
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003493 * The first role is to log input interaction with windows, which helps determine what the user was
3494 * interacting with. For example, if user is touching launcher, we will see an input_interaction log
3495 * that user started interacting with launcher window, as well as any other window that received
3496 * that gesture, such as the wallpaper or other spy windows. A new input_interaction is only logged
3497 * when the set of tokens that received the event changes. It is not logged again as long as the
3498 * user is interacting with the same windows.
3499 *
3500 * The second role is to track input device activity for metrics collection. For each input event,
3501 * we report the set of UIDs that the input device interacted with to the policy. Unlike for the
3502 * input_interaction logs, the device interaction is reported even when the set of interaction
3503 * tokens do not change.
3504 *
3505 * For these purposes, we do not count ACTION_OUTSIDE, ACTION_UP and ACTION_CANCEL actions as
3506 * interaction. This includes up and cancel events for both keys and motions.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003507 */
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003508void InputDispatcher::processInteractionsLocked(const EventEntry& entry,
3509 const std::vector<InputTarget>& targets) {
3510 int32_t deviceId;
3511 nsecs_t eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003512 // Skip ACTION_UP events, and all events other than keys and motions
3513 if (entry.type == EventEntry::Type::KEY) {
3514 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3515 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3516 return;
3517 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003518 deviceId = keyEntry.deviceId;
3519 eventTime = keyEntry.eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003520 } else if (entry.type == EventEntry::Type::MOTION) {
3521 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3522 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003523 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
3524 MotionEvent::getActionMasked(motionEntry.action) == AMOTION_EVENT_ACTION_POINTER_UP) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003525 return;
3526 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003527 deviceId = motionEntry.deviceId;
3528 eventTime = motionEntry.eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003529 } else {
3530 return; // Not a key or a motion
3531 }
3532
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003533 std::set<gui::Uid> interactionUids;
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003534 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003535 std::vector<std::shared_ptr<Connection>> newConnections;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003536 for (const InputTarget& target : targets) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003537 if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003538 continue; // Skip windows that receive ACTION_OUTSIDE
3539 }
3540
3541 sp<IBinder> token = target.inputChannel->getConnectionToken();
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003542 std::shared_ptr<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003543 if (connection == nullptr) {
3544 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003545 }
3546 newConnectionTokens.insert(std::move(token));
3547 newConnections.emplace_back(connection);
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003548 if (target.windowHandle) {
3549 interactionUids.emplace(target.windowHandle->getInfo()->ownerUid);
3550 }
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003551 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003552
3553 auto command = [this, deviceId, eventTime, uids = std::move(interactionUids)]()
3554 REQUIRES(mLock) {
3555 scoped_unlock unlock(mLock);
3556 mPolicy.notifyDeviceInteraction(deviceId, eventTime, uids);
3557 };
3558 postCommandLocked(std::move(command));
3559
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003560 if (newConnectionTokens == mInteractionConnectionTokens) {
3561 return; // no change
3562 }
3563 mInteractionConnectionTokens = newConnectionTokens;
3564
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003565 std::string targetList;
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003566 for (const std::shared_ptr<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003567 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003568 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003569 std::string message = "Interaction with: " + targetList;
3570 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003571 message += "<none>";
3572 }
3573 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3574}
3575
chaviwfd6d3512019-03-25 13:23:49 -07003576void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003577 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003578 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003579 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3580 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003581 return;
3582 }
3583
Vishnu Nairc519ff72021-01-21 08:23:08 -08003584 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003585 if (focusedToken == token) {
3586 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003587 return;
3588 }
3589
Prabir Pradhancef936d2021-07-21 16:17:52 +00003590 auto command = [this, token]() REQUIRES(mLock) {
3591 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003592 mPolicy.onPointerDownOutsideFocus(token);
Prabir Pradhancef936d2021-07-21 16:17:52 +00003593 };
3594 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003595}
3596
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003597status_t InputDispatcher::publishMotionEvent(Connection& connection,
3598 DispatchEntry& dispatchEntry) const {
3599 const EventEntry& eventEntry = *(dispatchEntry.eventEntry);
3600 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3601
3602 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003603 const PointerCoords* usingCoords = motionEntry.pointerCoords.data();
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003604
3605 // Set the X and Y offset and X and Y scale depending on the input source.
3606 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003607 !(dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS))) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003608 float globalScaleFactor = dispatchEntry.globalScaleFactor;
3609 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003610 for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003611 scaledCoords[i] = motionEntry.pointerCoords[i];
3612 // Don't apply window scale here since we don't want scale to affect raw
3613 // coordinates. The scale will be sent back to the client and applied
3614 // later when requesting relative coordinates.
Harry Cutts33476232023-01-30 19:57:29 +00003615 scaledCoords[i].scale(globalScaleFactor, /*windowXScale=*/1, /*windowYScale=*/1);
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003616 }
3617 usingCoords = scaledCoords;
3618 }
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003619 } else if (dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS)) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003620 // We don't want the dispatch target to know the coordinates
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003621 for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003622 scaledCoords[i].clear();
3623 }
3624 usingCoords = scaledCoords;
3625 }
3626
3627 std::array<uint8_t, 32> hmac = getSignature(motionEntry, dispatchEntry);
3628
3629 // Publish the motion event.
3630 return connection.inputPublisher
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003631 .publishMotionEvent(dispatchEntry.seq, motionEntry.id, motionEntry.deviceId,
3632 motionEntry.source, motionEntry.displayId, std::move(hmac),
3633 motionEntry.action, motionEntry.actionButton,
3634 dispatchEntry.resolvedFlags, motionEntry.edgeFlags,
3635 motionEntry.metaState, motionEntry.buttonState,
3636 motionEntry.classification, dispatchEntry.transform,
3637 motionEntry.xPrecision, motionEntry.yPrecision,
3638 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
3639 dispatchEntry.rawTransform, motionEntry.downTime,
3640 motionEntry.eventTime, motionEntry.getPointerCount(),
3641 motionEntry.pointerProperties.data(), usingCoords);
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003642}
3643
Michael Wrightd02c5b62014-02-10 15:10:22 -08003644void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003645 const std::shared_ptr<Connection>& connection) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003646 ATRACE_NAME_IF(ATRACE_ENABLED(),
3647 StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
3648 connection->getInputChannelName().c_str()));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003649 if (DEBUG_DISPATCH_CYCLE) {
3650 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3651 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003652
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003653 while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003654 std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003655 dispatchEntry->deliveryTime = currentTime;
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08003656 const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003657 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003658
3659 // Publish the event.
3660 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003661 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3662 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003663 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003664 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3665 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003666 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003667 LOG(INFO) << "Publishing " << *dispatchEntry << " to "
3668 << connection->getInputChannelName();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003669 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003670
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003671 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003672 status = connection->inputPublisher
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003673 .publishKeyEvent(dispatchEntry->seq, keyEntry.id,
3674 keyEntry.deviceId, keyEntry.source,
3675 keyEntry.displayId, std::move(hmac),
3676 keyEntry.action, dispatchEntry->resolvedFlags,
3677 keyEntry.keyCode, keyEntry.scanCode,
3678 keyEntry.metaState, keyEntry.repeatCount,
3679 keyEntry.downTime, keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003680 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003681 }
3682
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003683 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003684 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003685 LOG(INFO) << "Publishing " << *dispatchEntry << " to "
3686 << connection->getInputChannelName();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003687 }
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003688 status = publishMotionEvent(*connection, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003689 break;
3690 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003691
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003692 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003693 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003694 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003695 focusEntry.id,
Antonio Kantek3cfec7b2021-11-05 18:26:17 -07003696 focusEntry.hasFocus);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003697 break;
3698 }
3699
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003700 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3701 const TouchModeEntry& touchModeEntry =
3702 static_cast<const TouchModeEntry&>(eventEntry);
3703 status = connection->inputPublisher
3704 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3705 touchModeEntry.inTouchMode);
3706
3707 break;
3708 }
3709
Prabir Pradhan99987712020-11-10 18:43:05 -08003710 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3711 const auto& captureEntry =
3712 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3713 status = connection->inputPublisher
3714 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003715 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003716 break;
3717 }
3718
arthurhungb89ccb02020-12-30 16:19:01 +08003719 case EventEntry::Type::DRAG: {
3720 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3721 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3722 dragEntry.id, dragEntry.x,
3723 dragEntry.y,
3724 dragEntry.isExiting);
3725 break;
3726 }
3727
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003728 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003729 case EventEntry::Type::DEVICE_RESET:
3730 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003731 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003732 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003733 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003734 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003735 }
3736
3737 // Check the result.
3738 if (status) {
3739 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003740 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003741 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003742 "This is unexpected because the wait queue is empty, so the pipe "
3743 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003744 "event to it, status=%s(%d)",
3745 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3746 status);
Harry Cutts33476232023-01-30 19:57:29 +00003747 abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003748 } else {
3749 // Pipe is full and we are waiting for the app to finish process some events
3750 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003751 if (DEBUG_DISPATCH_CYCLE) {
3752 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3753 "waiting for the application to catch up",
3754 connection->getInputChannelName().c_str());
3755 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003756 }
3757 } else {
3758 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003759 "status=%s(%d)",
3760 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3761 status);
Harry Cutts33476232023-01-30 19:57:29 +00003762 abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003763 }
3764 return;
3765 }
3766
3767 // Re-enqueue the event on the wait queue.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003768 const nsecs_t timeoutTime = dispatchEntry->timeoutTime;
3769 connection->waitQueue.emplace_back(std::move(dispatchEntry));
3770 connection->outboundQueue.erase(connection->outboundQueue.begin());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003771 traceOutboundQueueLength(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003772 if (connection->responsive) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003773 mAnrTracker.insert(timeoutTime, connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003774 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003775 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003776 }
3777}
3778
chaviw09c8d2d2020-08-24 15:48:26 -07003779std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3780 size_t size;
3781 switch (event.type) {
3782 case VerifiedInputEvent::Type::KEY: {
3783 size = sizeof(VerifiedKeyEvent);
3784 break;
3785 }
3786 case VerifiedInputEvent::Type::MOTION: {
3787 size = sizeof(VerifiedMotionEvent);
3788 break;
3789 }
3790 }
3791 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3792 return mHmacKeyManager.sign(start, size);
3793}
3794
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003795const std::array<uint8_t, 32> InputDispatcher::getSignature(
3796 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003797 const int32_t actionMasked = MotionEvent::getActionMasked(motionEntry.action);
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003798 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003799 // Only sign events up and down events as the purely move events
3800 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003801 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003802 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003803
3804 VerifiedMotionEvent verifiedEvent =
3805 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3806 verifiedEvent.actionMasked = actionMasked;
3807 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3808 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003809}
3810
3811const std::array<uint8_t, 32> InputDispatcher::getSignature(
3812 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3813 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3814 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003815 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003816}
3817
Michael Wrightd02c5b62014-02-10 15:10:22 -08003818void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003819 const std::shared_ptr<Connection>& connection,
3820 uint32_t seq, bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003821 if (DEBUG_DISPATCH_CYCLE) {
3822 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3823 connection->getInputChannelName().c_str(), seq, toString(handled));
3824 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003825
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003826 if (connection->status == Connection::Status::BROKEN ||
3827 connection->status == Connection::Status::ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003828 return;
3829 }
3830
3831 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003832 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3833 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3834 };
3835 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003836}
3837
3838void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003839 const std::shared_ptr<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003840 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003841 if (DEBUG_DISPATCH_CYCLE) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003842 LOG(INFO) << "channel '" << connection->getInputChannelName() << "'~ " << __func__
3843 << " - notify=" << toString(notify);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003844 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003845
3846 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003847 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003848 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003849 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003850 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003851
3852 // The connection appears to be unrecoverably broken.
3853 // Ignore already broken or zombie connections.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003854 if (connection->status == Connection::Status::NORMAL) {
3855 connection->status = Connection::Status::BROKEN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003856
3857 if (notify) {
3858 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003859 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3860 connection->getInputChannelName().c_str());
3861
3862 auto command = [this, connection]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003863 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003864 mPolicy.notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Prabir Pradhancef936d2021-07-21 16:17:52 +00003865 };
3866 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003867 }
3868 }
3869}
3870
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003871void InputDispatcher::drainDispatchQueue(std::deque<std::unique_ptr<DispatchEntry>>& queue) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003872 while (!queue.empty()) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003873 releaseDispatchEntry(std::move(queue.front()));
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003874 queue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003875 }
3876}
3877
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003878void InputDispatcher::releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003879 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003880 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003881 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003882}
3883
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003884int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3885 std::scoped_lock _l(mLock);
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003886 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003887 if (connection == nullptr) {
3888 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3889 connectionToken.get(), events);
3890 return 0; // remove the callback
3891 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003892
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003893 bool notify;
3894 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3895 if (!(events & ALOOPER_EVENT_INPUT)) {
3896 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3897 "events=0x%x",
3898 connection->getInputChannelName().c_str(), events);
3899 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003900 }
3901
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003902 nsecs_t currentTime = now();
3903 bool gotOne = false;
3904 status_t status = OK;
3905 for (;;) {
3906 Result<InputPublisher::ConsumerResponse> result =
3907 connection->inputPublisher.receiveConsumerResponse();
3908 if (!result.ok()) {
3909 status = result.error().code();
3910 break;
3911 }
3912
3913 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3914 const InputPublisher::Finished& finish =
3915 std::get<InputPublisher::Finished>(*result);
3916 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3917 finish.consumeTime);
3918 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003919 if (shouldReportMetricsForConnection(*connection)) {
3920 const InputPublisher::Timeline& timeline =
3921 std::get<InputPublisher::Timeline>(*result);
3922 mLatencyTracker
3923 .trackGraphicsLatency(timeline.inputEventId,
3924 connection->inputChannel->getConnectionToken(),
3925 std::move(timeline.graphicsTimeline));
3926 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003927 }
3928 gotOne = true;
3929 }
3930 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003931 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003932 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003933 return 1;
3934 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003935 }
3936
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003937 notify = status != DEAD_OBJECT || !connection->monitor;
3938 if (notify) {
3939 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3940 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3941 status);
3942 }
3943 } else {
3944 // Monitor channels are never explicitly unregistered.
3945 // We do it automatically when the remote endpoint is closed so don't warn about them.
3946 const bool stillHaveWindowHandle =
3947 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3948 notify = !connection->monitor && stillHaveWindowHandle;
3949 if (notify) {
3950 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3951 connection->getInputChannelName().c_str(), events);
3952 }
3953 }
3954
3955 // Remove the channel.
3956 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3957 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003958}
3959
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003960void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003961 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003962 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003963 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003964 }
3965}
3966
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003967void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003968 const CancelationOptions& options) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08003969 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003970 for (const Monitor& monitor : monitors) {
3971 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003972 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003973 }
3974}
3975
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003977 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003978 std::shared_ptr<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003979 if (connection == nullptr) {
3980 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003981 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003982
3983 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003984}
3985
3986void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003987 const std::shared_ptr<Connection>& connection, const CancelationOptions& options) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003988 if (connection->status == Connection::Status::BROKEN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003989 return;
3990 }
3991
3992 nsecs_t currentTime = now();
3993
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003994 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003995 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003996
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003997 if (cancelationEvents.empty()) {
3998 return;
3999 }
Vaibhav Devmurari110ba322023-11-17 10:47:16 +00004000
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004001 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
4002 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Siarhei Vishniakou2e3e4432023-02-09 18:34:11 -08004003 "with reality: %s, mode=%s.",
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004004 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
Siarhei Vishniakou2e3e4432023-02-09 18:34:11 -08004005 ftl::enum_string(options.mode).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004006 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08004007
Arthur Hungb3307ee2021-10-14 10:57:37 +00004008 std::string reason = std::string("reason=").append(options.reason);
4009 android_log_event_list(LOGTAG_INPUT_CANCEL)
4010 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
4011
hongzuo liu95785e22022-09-06 02:51:35 +00004012 const bool wasEmpty = connection->outboundQueue.empty();
Prabir Pradhan16463382023-10-12 23:03:19 +00004013 // The target to use if we don't find a window associated with the channel.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004014 const InputTarget fallbackTarget{.inputChannel = connection->inputChannel};
Prabir Pradhan16463382023-10-12 23:03:19 +00004015 const auto& token = connection->inputChannel->getConnectionToken();
hongzuo liu95785e22022-09-06 02:51:35 +00004016
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004017 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004018 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004019 std::vector<InputTarget> targets{};
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004020
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004021 switch (cancelationEventEntry->type) {
4022 case EventEntry::Type::KEY: {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004023 const auto& keyEntry = static_cast<const KeyEntry&>(*cancelationEventEntry);
Prabir Pradhan16463382023-10-12 23:03:19 +00004024 const std::optional<int32_t> targetDisplay = keyEntry.displayId != ADISPLAY_ID_NONE
4025 ? std::make_optional(keyEntry.displayId)
4026 : std::nullopt;
4027 if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004028 addWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
4029 /*targetFlags=*/{}, keyEntry.downTime, targets);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004030 } else {
4031 targets.emplace_back(fallbackTarget);
4032 }
4033 logOutboundKeyDetails("cancel - ", keyEntry);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004034 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004035 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004036 case EventEntry::Type::MOTION: {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004037 const auto& motionEntry = static_cast<const MotionEntry&>(*cancelationEventEntry);
Prabir Pradhan16463382023-10-12 23:03:19 +00004038 const std::optional<int32_t> targetDisplay =
4039 motionEntry.displayId != ADISPLAY_ID_NONE
4040 ? std::make_optional(motionEntry.displayId)
4041 : std::nullopt;
4042 if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004043 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004044 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004045 pointerIndex++) {
4046 pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4047 }
Vaibhav Devmurari110ba322023-11-17 10:47:16 +00004048 if (mDragState && mDragState->dragWindow->getToken() == token &&
4049 pointerIds.test(mDragState->pointerId)) {
4050 LOG(INFO) << __func__
4051 << ": Canceling drag and drop because the pointers for the drag "
4052 "window are being canceled.";
4053 sendDropWindowCommandLocked(nullptr, /*x=*/0, /*y=*/0);
4054 mDragState.reset();
4055 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004056 addPointerWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
4057 ftl::Flags<InputTarget::Flags>(), pointerIds,
4058 motionEntry.downTime, targets);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004059 } else {
4060 targets.emplace_back(fallbackTarget);
4061 const auto it = mDisplayInfos.find(motionEntry.displayId);
4062 if (it != mDisplayInfos.end()) {
4063 targets.back().displayTransform = it->second.transform;
4064 targets.back().setDefaultPointerTransform(it->second.transform);
4065 }
4066 }
4067 logOutboundMotionDetails("cancel - ", motionEntry);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004068 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004069 }
Prabir Pradhan99987712020-11-10 18:43:05 -08004070 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004071 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08004072 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
4073 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08004074 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08004075 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004076 break;
4077 }
4078 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07004079 case EventEntry::Type::DEVICE_RESET:
4080 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004081 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08004082 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004083 break;
4084 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004085 }
4086
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004087 if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004088 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), targets[0]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004089 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004090
hongzuo liu95785e22022-09-06 02:51:35 +00004091 // If the outbound queue was previously empty, start the dispatch cycle going.
4092 if (wasEmpty && !connection->outboundQueue.empty()) {
4093 startDispatchCycleLocked(currentTime, connection);
4094 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004095}
4096
Svet Ganov5d3bc372020-01-26 23:11:07 -08004097void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07004098 const nsecs_t downTime, const std::shared_ptr<Connection>& connection,
Arthur Hungc539dbb2022-12-08 07:45:36 +00004099 ftl::Flags<InputTarget::Flags> targetFlags) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08004100 if (connection->status == Connection::Status::BROKEN) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004101 return;
4102 }
4103
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004104 std::vector<std::unique_ptr<EventEntry>> downEvents =
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004105 connection->inputState.synthesizePointerDownEvents(downTime);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004106
4107 if (downEvents.empty()) {
4108 return;
4109 }
4110
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004111 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004112 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
4113 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004114 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08004115
chaviw98318de2021-05-19 16:45:23 -05004116 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08004117 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Svet Ganov5d3bc372020-01-26 23:11:07 -08004118
hongzuo liu95785e22022-09-06 02:51:35 +00004119 const bool wasEmpty = connection->outboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004120 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004121 std::vector<InputTarget> targets{};
Svet Ganov5d3bc372020-01-26 23:11:07 -08004122 switch (downEventEntry->type) {
4123 case EventEntry::Type::MOTION: {
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004124 const auto& motionEntry = static_cast<const MotionEntry&>(*downEventEntry);
4125 if (windowHandle != nullptr) {
4126 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004127 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004128 pointerIndex++) {
4129 pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4130 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004131 addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::AS_IS,
4132 targetFlags, pointerIds, motionEntry.downTime,
4133 targets);
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004134 } else {
4135 targets.emplace_back(InputTarget{.inputChannel = connection->inputChannel,
4136 .flags = targetFlags});
4137 const auto it = mDisplayInfos.find(motionEntry.displayId);
4138 if (it != mDisplayInfos.end()) {
4139 targets.back().displayTransform = it->second.transform;
4140 targets.back().setDefaultPointerTransform(it->second.transform);
4141 }
4142 }
4143 logOutboundMotionDetails("down - ", motionEntry);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004144 break;
4145 }
4146
4147 case EventEntry::Type::KEY:
4148 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004149 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08004150 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08004151 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07004152 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08004153 case EventEntry::Type::SENSOR:
4154 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004155 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08004156 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08004157 break;
4158 }
4159 }
4160
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004161 if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004162 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), targets[0]);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004163 }
4164
hongzuo liu95785e22022-09-06 02:51:35 +00004165 // If the outbound queue was previously empty, start the dispatch cycle going.
4166 if (wasEmpty && !connection->outboundQueue.empty()) {
4167 startDispatchCycleLocked(downTime, connection);
4168 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08004169}
4170
Arthur Hungc539dbb2022-12-08 07:45:36 +00004171void InputDispatcher::synthesizeCancelationEventsForWindowLocked(
4172 const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options) {
4173 if (windowHandle != nullptr) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07004174 std::shared_ptr<Connection> wallpaperConnection =
4175 getConnectionLocked(windowHandle->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00004176 if (wallpaperConnection != nullptr) {
4177 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection, options);
4178 }
4179 }
4180}
4181
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004182std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004183 const MotionEntry& originalMotionEntry, std::bitset<MAX_POINTER_ID + 1> pointerIds,
4184 nsecs_t splitDownTime) {
4185 ALOG_ASSERT(pointerIds.any());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004186
4187 uint32_t splitPointerIndexMap[MAX_POINTERS];
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004188 std::vector<PointerProperties> splitPointerProperties;
4189 std::vector<PointerCoords> splitPointerCoords;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004190
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004191 uint32_t originalPointerCount = originalMotionEntry.getPointerCount();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004192 uint32_t splitPointerCount = 0;
4193
4194 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004195 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004196 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004197 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004198 uint32_t pointerId = uint32_t(pointerProperties.id);
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004199 if (pointerIds.test(pointerId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004200 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004201 splitPointerProperties.push_back(pointerProperties);
4202 splitPointerCoords.push_back(originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004203 splitPointerCount += 1;
4204 }
4205 }
4206
4207 if (splitPointerCount != pointerIds.count()) {
4208 // This is bad. We are missing some of the pointers that we expected to deliver.
4209 // Most likely this indicates that we received an ACTION_MOVE events that has
4210 // different pointer ids than we expected based on the previous ACTION_DOWN
4211 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
4212 // in this way.
4213 ALOGW("Dropping split motion event because the pointer count is %d but "
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004214 "we expected there to be %zu pointers. This probably means we received "
Siarhei Vishniakou16e4fa02023-02-16 17:48:56 -08004215 "a broken sequence of pointer ids from the input device: %s",
4216 splitPointerCount, pointerIds.count(), originalMotionEntry.getDescription().c_str());
Yi Kong9b14ac62018-07-17 13:48:38 -07004217 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004218 }
4219
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004220 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004221 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004222 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
4223 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07004224 int32_t originalPointerIndex = MotionEvent::getActionIndex(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004225 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004226 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004227 uint32_t pointerId = uint32_t(pointerProperties.id);
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004228 if (pointerIds.test(pointerId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004229 if (pointerIds.count() == 1) {
4230 // The first/last pointer went down/up.
4231 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004232 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08004233 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
4234 ? AMOTION_EVENT_ACTION_CANCEL
4235 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004236 } else {
4237 // A secondary pointer went down/up.
4238 uint32_t splitPointerIndex = 0;
4239 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
4240 splitPointerIndex += 1;
4241 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004242 action = maskedAction |
4243 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004244 }
4245 } else {
4246 // An unrelated pointer changed.
4247 action = AMOTION_EVENT_ACTION_MOVE;
4248 }
4249 }
4250
Siarhei Vishniakou59e302b2023-06-05 08:04:53 -07004251 if (action == AMOTION_EVENT_ACTION_DOWN && splitDownTime != originalMotionEntry.eventTime) {
4252 logDispatchStateLocked();
4253 LOG_ALWAYS_FATAL("Split motion event has mismatching downTime and eventTime for "
4254 "ACTION_DOWN, motionEntry=%s, splitDownTime=%" PRId64,
4255 originalMotionEntry.getDescription().c_str(), splitDownTime);
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004256 }
4257
Garfield Tanff1f1bb2020-01-28 13:24:04 -08004258 int32_t newId = mIdGenerator.nextId();
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00004259 ATRACE_NAME_IF(ATRACE_ENABLED(),
4260 StringPrintf("Split MotionEvent(id=0x%" PRIx32 ") to MotionEvent(id=0x%" PRIx32
4261 ").",
4262 originalMotionEntry.id, newId));
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004263 std::unique_ptr<MotionEntry> splitMotionEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004264 std::make_unique<MotionEntry>(newId, originalMotionEntry.injectionState,
4265 originalMotionEntry.eventTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004266 originalMotionEntry.deviceId, originalMotionEntry.source,
4267 originalMotionEntry.displayId,
4268 originalMotionEntry.policyFlags, action,
4269 originalMotionEntry.actionButton,
4270 originalMotionEntry.flags, originalMotionEntry.metaState,
4271 originalMotionEntry.buttonState,
4272 originalMotionEntry.classification,
4273 originalMotionEntry.edgeFlags,
4274 originalMotionEntry.xPrecision,
4275 originalMotionEntry.yPrecision,
4276 originalMotionEntry.xCursorPosition,
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004277 originalMotionEntry.yCursorPosition, splitDownTime,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004278 splitPointerProperties, splitPointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004279
Michael Wrightd02c5b62014-02-10 15:10:22 -08004280 return splitMotionEntry;
4281}
4282
Asmita Poddardd9a6cd2023-09-26 15:35:12 +00004283void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
4284 std::scoped_lock _l(mLock);
4285 mLatencyTracker.setInputDevices(args.inputDeviceInfos);
4286}
4287
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004288void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004289 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004290 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args.eventTime);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004291 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004292
Antonio Kantekf16f2832021-09-28 04:39:20 +00004293 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004294 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004295 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004296
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004297 std::unique_ptr<ConfigurationChangedEntry> newEntry =
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004298 std::make_unique<ConfigurationChangedEntry>(args.id, args.eventTime);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004299 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004300 } // release lock
4301
4302 if (needWake) {
4303 mLooper->wake();
4304 }
4305}
4306
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004307void InputDispatcher::notifyKey(const NotifyKeyArgs& args) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004308 ALOGD_IF(debugInboundEventDetails(),
4309 "notifyKey - id=%" PRIx32 ", eventTime=%" PRId64
4310 ", deviceId=%d, source=%s, displayId=%" PRId32
4311 "policyFlags=0x%x, action=%s, flags=0x%x, keyCode=%s, scanCode=0x%x, metaState=0x%x, "
4312 "downTime=%" PRId64,
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004313 args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4314 args.displayId, args.policyFlags, KeyEvent::actionToString(args.action), args.flags,
4315 KeyEvent::getLabel(args.keyCode), args.scanCode, args.metaState, args.downTime);
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004316 Result<void> keyCheck = validateKeyEvent(args.action);
4317 if (!keyCheck.ok()) {
4318 LOG(ERROR) << "invalid key event: " << keyCheck.error();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004319 return;
4320 }
4321
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004322 uint32_t policyFlags = args.policyFlags;
4323 int32_t flags = args.flags;
4324 int32_t metaState = args.metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07004325 // InputDispatcher tracks and generates key repeats on behalf of
4326 // whatever notifies it, so repeatCount should always be set to 0
4327 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004328 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
4329 policyFlags |= POLICY_FLAG_VIRTUAL;
4330 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
4331 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004332 if (policyFlags & POLICY_FLAG_FUNCTION) {
4333 metaState |= AMETA_FUNCTION_ON;
4334 }
4335
4336 policyFlags |= POLICY_FLAG_TRUSTED;
4337
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004338 int32_t keyCode = args.keyCode;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004339 KeyEvent event;
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004340 event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC, args.action,
4341 flags, keyCode, args.scanCode, metaState, repeatCount, args.downTime,
4342 args.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004343
Michael Wright2b3c3302018-03-02 17:19:13 +00004344 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004345 mPolicy.interceptKeyBeforeQueueing(event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004346 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4347 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004348 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004349 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004350
Antonio Kantekf16f2832021-09-28 04:39:20 +00004351 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004352 { // acquire lock
4353 mLock.lock();
4354
4355 if (shouldSendKeyToInputFilterLocked(args)) {
4356 mLock.unlock();
4357
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004358 policyFlags |= POLICY_FLAG_FILTERED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004359 if (!mPolicy.filterInputEvent(event, policyFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004360 return; // event was consumed by the filter
4361 }
4362
4363 mLock.lock();
4364 }
4365
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004366 std::unique_ptr<KeyEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004367 std::make_unique<KeyEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4368 args.deviceId, args.source, args.displayId, policyFlags,
4369 args.action, flags, keyCode, args.scanCode, metaState,
4370 repeatCount, args.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004371
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004372 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004373 mLock.unlock();
4374 } // release lock
4375
4376 if (needWake) {
4377 mLooper->wake();
4378 }
4379}
4380
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004381bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs& args) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004382 return mInputFilterEnabled;
4383}
4384
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004385void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004386 if (debugInboundEventDetails()) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004387 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=%s, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004388 "displayId=%" PRId32 ", policyFlags=0x%x, "
Siarhei Vishniakou6ebd0692022-10-20 15:05:45 -07004389 "action=%s, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004390 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
4391 "yCursorPosition=%f, downTime=%" PRId64,
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004392 args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4393 args.displayId, args.policyFlags, MotionEvent::actionToString(args.action).c_str(),
4394 args.actionButton, args.flags, args.metaState, args.buttonState, args.edgeFlags,
4395 args.xPrecision, args.yPrecision, args.xCursorPosition, args.yCursorPosition,
4396 args.downTime);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004397 for (uint32_t i = 0; i < args.getPointerCount(); i++) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004398 ALOGD(" Pointer %d: id=%d, toolType=%s, x=%f, y=%f, pressure=%f, size=%f, "
4399 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, orientation=%f",
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004400 i, args.pointerProperties[i].id,
4401 ftl::enum_string(args.pointerProperties[i].toolType).c_str(),
4402 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
4403 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
4404 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
4405 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
4406 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
4407 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
4408 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
4409 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
4410 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004411 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004412 }
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004413
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004414 Result<void> motionCheck =
4415 validateMotionEvent(args.action, args.actionButton, args.getPointerCount(),
4416 args.pointerProperties.data());
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004417 if (!motionCheck.ok()) {
4418 LOG(FATAL) << "Invalid event: " << args.dump() << "; reason: " << motionCheck.error();
4419 return;
4420 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004421
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07004422 if (DEBUG_VERIFY_EVENTS) {
4423 auto [it, _] =
4424 mVerifiersByDisplay.try_emplace(args.displayId,
4425 StringPrintf("display %" PRId32, args.displayId));
4426 Result<void> result =
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -07004427 it->second.processMovement(args.deviceId, args.source, args.action,
4428 args.getPointerCount(), args.pointerProperties.data(),
4429 args.pointerCoords.data(), args.flags);
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07004430 if (!result.ok()) {
4431 LOG(FATAL) << "Bad stream: " << result.error() << " caused by " << args.dump();
4432 }
4433 }
4434
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004435 uint32_t policyFlags = args.policyFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004436 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004437
4438 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004439 mPolicy.interceptMotionBeforeQueueing(args.displayId, args.eventTime, policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004440 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4441 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004442 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004443 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004444
Antonio Kantekf16f2832021-09-28 04:39:20 +00004445 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004446 { // acquire lock
4447 mLock.lock();
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004448 if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
4449 // Set the flag anyway if we already have an ongoing gesture. That would allow us to
4450 // complete the processing of the current stroke.
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004451 const auto touchStateIt = mTouchStatesByDisplay.find(args.displayId);
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004452 if (touchStateIt != mTouchStatesByDisplay.end()) {
4453 const TouchState& touchState = touchStateIt->second;
Linnan Li907ae732023-09-05 17:14:21 +08004454 if (touchState.hasTouchingPointers(args.deviceId) ||
4455 touchState.hasHoveringPointers(args.deviceId)) {
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004456 policyFlags |= POLICY_FLAG_PASS_TO_USER;
4457 }
4458 }
4459 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004460
4461 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004462 ui::Transform displayTransform;
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004463 if (const auto it = mDisplayInfos.find(args.displayId); it != mDisplayInfos.end()) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004464 displayTransform = it->second.transform;
4465 }
4466
Michael Wrightd02c5b62014-02-10 15:10:22 -08004467 mLock.unlock();
4468
4469 MotionEvent event;
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004470 event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC,
4471 args.action, args.actionButton, args.flags, args.edgeFlags,
4472 args.metaState, args.buttonState, args.classification,
4473 displayTransform, args.xPrecision, args.yPrecision,
4474 args.xCursorPosition, args.yCursorPosition, displayTransform,
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004475 args.downTime, args.eventTime, args.getPointerCount(),
4476 args.pointerProperties.data(), args.pointerCoords.data());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004477
4478 policyFlags |= POLICY_FLAG_FILTERED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004479 if (!mPolicy.filterInputEvent(event, policyFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004480 return; // event was consumed by the filter
4481 }
4482
4483 mLock.lock();
4484 }
4485
4486 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004487 std::unique_ptr<MotionEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004488 std::make_unique<MotionEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4489 args.deviceId, args.source, args.displayId,
4490 policyFlags, args.action, args.actionButton,
4491 args.flags, args.metaState, args.buttonState,
4492 args.classification, args.edgeFlags, args.xPrecision,
4493 args.yPrecision, args.xCursorPosition,
4494 args.yCursorPosition, args.downTime,
4495 args.pointerProperties, args.pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004496
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004497 if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4498 IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004499 !mInputFilterEnabled) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004500 const bool isDown = args.action == AMOTION_EVENT_ACTION_DOWN;
Asmita Poddardd9a6cd2023-09-26 15:35:12 +00004501 std::set<InputDeviceUsageSource> sources = getUsageSourcesForMotionArgs(args);
4502 mLatencyTracker.trackListener(args.id, isDown, args.eventTime, args.readTime,
4503 args.deviceId, sources);
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004504 }
4505
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004506 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004507 mLock.unlock();
4508 } // release lock
4509
4510 if (needWake) {
4511 mLooper->wake();
4512 }
4513}
4514
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004515void InputDispatcher::notifySensor(const NotifySensorArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004516 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004517 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4518 " sensorType=%s",
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004519 args.id, args.eventTime, args.deviceId, args.source,
4520 ftl::enum_string(args.sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004521 }
Chris Yef59a2f42020-10-16 12:55:26 -07004522
Antonio Kantekf16f2832021-09-28 04:39:20 +00004523 bool needWake = false;
Chris Yef59a2f42020-10-16 12:55:26 -07004524 { // acquire lock
4525 mLock.lock();
4526
4527 // Just enqueue a new sensor event.
4528 std::unique_ptr<SensorEntry> newEntry =
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004529 std::make_unique<SensorEntry>(args.id, args.eventTime, args.deviceId, args.source,
4530 /* policyFlags=*/0, args.hwTimestamp, args.sensorType,
4531 args.accuracy, args.accuracyChanged, args.values);
Chris Yef59a2f42020-10-16 12:55:26 -07004532
4533 needWake = enqueueInboundEventLocked(std::move(newEntry));
4534 mLock.unlock();
4535 } // release lock
4536
4537 if (needWake) {
4538 mLooper->wake();
4539 }
4540}
4541
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004542void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004543 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004544 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args.eventTime,
4545 args.deviceId, args.isOn);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004546 }
Prabir Pradhana41d2442023-04-20 21:30:40 +00004547 mPolicy.notifyVibratorState(args.deviceId, args.isOn);
Chris Yefb552902021-02-03 17:18:37 -08004548}
4549
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004550bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs& args) {
Jackal Guof9696682018-10-05 12:23:23 +08004551 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004552}
4553
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004554void InputDispatcher::notifySwitch(const NotifySwitchArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004555 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004556 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4557 "switchMask=0x%08x",
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004558 args.eventTime, args.policyFlags, args.switchValues, args.switchMask);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004559 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004560
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004561 uint32_t policyFlags = args.policyFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004562 policyFlags |= POLICY_FLAG_TRUSTED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004563 mPolicy.notifySwitch(args.eventTime, args.switchValues, args.switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004564}
4565
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004566void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004567 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004568 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args.eventTime,
4569 args.deviceId);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004570 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004571
Antonio Kantekf16f2832021-09-28 04:39:20 +00004572 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004573 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004574 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004575
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004576 std::unique_ptr<DeviceResetEntry> newEntry =
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004577 std::make_unique<DeviceResetEntry>(args.id, args.eventTime, args.deviceId);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004578 needWake = enqueueInboundEventLocked(std::move(newEntry));
Siarhei Vishniakou1160ecd2023-06-28 15:57:47 -07004579
4580 for (auto& [_, verifier] : mVerifiersByDisplay) {
4581 verifier.resetDevice(args.deviceId);
4582 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004583 } // release lock
4584
4585 if (needWake) {
4586 mLooper->wake();
4587 }
4588}
4589
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004590void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004591 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004592 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args.eventTime,
4593 args.request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004594 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004595
Antonio Kantekf16f2832021-09-28 04:39:20 +00004596 bool needWake = false;
Prabir Pradhan99987712020-11-10 18:43:05 -08004597 { // acquire lock
4598 std::scoped_lock _l(mLock);
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004599 auto entry =
4600 std::make_unique<PointerCaptureChangedEntry>(args.id, args.eventTime, args.request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004601 needWake = enqueueInboundEventLocked(std::move(entry));
4602 } // release lock
4603
4604 if (needWake) {
4605 mLooper->wake();
4606 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004607}
4608
Prabir Pradhan5735a322022-04-11 17:23:34 +00004609InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* event,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00004610 std::optional<gui::Uid> targetUid,
Prabir Pradhan5735a322022-04-11 17:23:34 +00004611 InputEventInjectionSync syncMode,
4612 std::chrono::milliseconds timeout,
4613 uint32_t policyFlags) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004614 Result<void> eventValidation = validateInputEvent(*event);
4615 if (!eventValidation.ok()) {
4616 LOG(INFO) << "Injection failed: invalid event: " << eventValidation.error();
4617 return InputEventInjectionResult::FAILED;
4618 }
4619
Prabir Pradhan65613802023-02-22 23:36:58 +00004620 if (debugInboundEventDetails()) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004621 LOG(INFO) << __func__ << ": targetUid=" << toString(targetUid, &uidString)
4622 << ", syncMode=" << ftl::enum_string(syncMode) << ", timeout=" << timeout.count()
4623 << "ms, policyFlags=0x" << std::hex << policyFlags << std::dec
4624 << ", event=" << *event;
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004625 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004626 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004627
Prabir Pradhan5735a322022-04-11 17:23:34 +00004628 policyFlags |= POLICY_FLAG_INJECTED | POLICY_FLAG_TRUSTED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004629
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004630 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004631 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4632 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4633 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4634 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4635 // from events that originate from actual hardware.
Siarhei Vishniakouf4043212023-09-18 19:33:03 -07004636 DeviceId resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004637 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004638 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004639 }
4640
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004641 const bool isAsync = syncMode == InputEventInjectionSync::NONE;
4642 auto injectionState = std::make_shared<InjectionState>(targetUid, isAsync);
4643
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004644 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004645 switch (event->getType()) {
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004646 case InputEventType::KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004647 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004648 const int32_t action = incomingKey.getAction();
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004649 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004650 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4651 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4652 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004653 int32_t keyCode = incomingKey.getKeyCode();
4654 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004655 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004656 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004657 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4658 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4659 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004660
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004661 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4662 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004663 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004664
4665 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4666 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004667 mPolicy.interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004668 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4669 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4670 std::to_string(t.duration().count()).c_str());
4671 }
4672 }
4673
4674 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004675 std::unique_ptr<KeyEntry> injectedEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004676 std::make_unique<KeyEntry>(incomingKey.getId(), injectionState,
4677 incomingKey.getEventTime(), resolvedDeviceId,
4678 incomingKey.getSource(), incomingKey.getDisplayId(),
4679 policyFlags, action, flags, keyCode,
4680 incomingKey.getScanCode(), metaState,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004681 incomingKey.getRepeatCount(),
4682 incomingKey.getDownTime());
4683 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004684 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004685 }
4686
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004687 case InputEventType::MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004688 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004689 const bool isPointerEvent =
4690 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4691 // If a pointer event has no displayId specified, inject it to the default display.
4692 const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
4693 ? ADISPLAY_ID_DEFAULT
4694 : event->getDisplayId();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004695 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004696
4697 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004698 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004699 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004700 mPolicy.interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004701 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4702 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4703 std::to_string(t.duration().count()).c_str());
4704 }
4705 }
4706
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004707 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4708 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4709 }
4710
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004711 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004712 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004713 const size_t pointerCount = motionEvent.getPointerCount();
4714 const std::vector<PointerProperties>
4715 pointerProperties(motionEvent.getPointerProperties(),
4716 motionEvent.getPointerProperties() + pointerCount);
4717
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004718 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004719 std::unique_ptr<MotionEntry> injectedEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004720 std::make_unique<MotionEntry>(motionEvent.getId(), injectionState,
4721 *sampleEventTimes, resolvedDeviceId,
4722 motionEvent.getSource(), displayId, policyFlags,
4723 motionEvent.getAction(),
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004724 motionEvent.getActionButton(), flags,
4725 motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004726 motionEvent.getButtonState(),
4727 motionEvent.getClassification(),
4728 motionEvent.getEdgeFlags(),
4729 motionEvent.getXPrecision(),
4730 motionEvent.getYPrecision(),
4731 motionEvent.getRawXCursorPosition(),
4732 motionEvent.getRawYCursorPosition(),
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004733 motionEvent.getDownTime(), pointerProperties,
4734 std::vector<PointerCoords>(samplePointerCoords,
4735 samplePointerCoords +
4736 pointerCount));
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004737 transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004738 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004739 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004740 sampleEventTimes += 1;
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004741 samplePointerCoords += motionEvent.getPointerCount();
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004742 std::unique_ptr<MotionEntry> nextInjectedEntry = std::make_unique<
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004743 MotionEntry>(motionEvent.getId(), injectionState, *sampleEventTimes,
4744 resolvedDeviceId, motionEvent.getSource(), displayId,
4745 policyFlags, motionEvent.getAction(),
4746 motionEvent.getActionButton(), flags,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004747 motionEvent.getMetaState(), motionEvent.getButtonState(),
4748 motionEvent.getClassification(), motionEvent.getEdgeFlags(),
4749 motionEvent.getXPrecision(), motionEvent.getYPrecision(),
4750 motionEvent.getRawXCursorPosition(),
4751 motionEvent.getRawYCursorPosition(), motionEvent.getDownTime(),
4752 pointerProperties,
4753 std::vector<PointerCoords>(samplePointerCoords,
4754 samplePointerCoords +
4755 pointerCount));
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004756 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
4757 motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004758 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004759 }
4760 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004761 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004762
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004763 default:
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004764 LOG(WARNING) << "Cannot inject " << ftl::enum_string(event->getType()) << " events";
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004765 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004766 }
4767
Michael Wrightd02c5b62014-02-10 15:10:22 -08004768 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004769 while (!injectedEntries.empty()) {
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08004770 if (DEBUG_INJECTION) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004771 LOG(INFO) << "Injecting " << injectedEntries.front()->getDescription();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08004772 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004773 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004774 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004775 }
4776
4777 mLock.unlock();
4778
4779 if (needWake) {
4780 mLooper->wake();
4781 }
4782
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004783 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004784 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004785 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004786
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004787 if (syncMode == InputEventInjectionSync::NONE) {
4788 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004789 } else {
4790 for (;;) {
4791 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004792 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004793 break;
4794 }
4795
4796 nsecs_t remainingTimeout = endTime - now();
4797 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004798 if (DEBUG_INJECTION) {
4799 ALOGD("injectInputEvent - Timed out waiting for injection result "
4800 "to become available.");
4801 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004802 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004803 break;
4804 }
4805
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004806 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004807 }
4808
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004809 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4810 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004811 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004812 if (DEBUG_INJECTION) {
4813 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4814 injectionState->pendingForegroundDispatches);
4815 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004816 nsecs_t remainingTimeout = endTime - now();
4817 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004818 if (DEBUG_INJECTION) {
4819 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4820 "dispatches to finish.");
4821 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004822 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004823 break;
4824 }
4825
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004826 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004827 }
4828 }
4829 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004830 } // release lock
4831
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004832 if (DEBUG_INJECTION) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004833 LOG(INFO) << "injectInputEvent - Finished with result "
4834 << ftl::enum_string(injectionResult);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004835 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004836
4837 return injectionResult;
4838}
4839
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004840std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004841 std::array<uint8_t, 32> calculatedHmac;
4842 std::unique_ptr<VerifiedInputEvent> result;
4843 switch (event.getType()) {
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004844 case InputEventType::KEY: {
Gang Wange9087892020-01-07 12:17:14 -05004845 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4846 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4847 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004848 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004849 break;
4850 }
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004851 case InputEventType::MOTION: {
Gang Wange9087892020-01-07 12:17:14 -05004852 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4853 VerifiedMotionEvent verifiedMotionEvent =
4854 verifiedMotionEventFromMotionEvent(motionEvent);
4855 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004856 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004857 break;
4858 }
4859 default: {
4860 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4861 return nullptr;
4862 }
4863 }
4864 if (calculatedHmac == INVALID_HMAC) {
4865 return nullptr;
4866 }
tyiu1573a672023-02-21 22:38:32 +00004867 if (0 != CRYPTO_memcmp(calculatedHmac.data(), event.getHmac().data(), calculatedHmac.size())) {
Gang Wange9087892020-01-07 12:17:14 -05004868 return nullptr;
4869 }
4870 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004871}
4872
Prabir Pradhan24047542023-11-02 17:14:59 +00004873void InputDispatcher::setInjectionResult(const EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004874 InputEventInjectionResult injectionResult) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004875 if (!entry.injectionState) {
4876 // Not an injected event.
4877 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004878 }
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004879
4880 InjectionState& injectionState = *entry.injectionState;
4881 if (DEBUG_INJECTION) {
4882 LOG(INFO) << "Setting input event injection result to "
4883 << ftl::enum_string(injectionResult);
4884 }
4885
4886 if (injectionState.injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
4887 // Log the outcome since the injector did not wait for the injection result.
4888 switch (injectionResult) {
4889 case InputEventInjectionResult::SUCCEEDED:
4890 ALOGV("Asynchronous input event injection succeeded.");
4891 break;
4892 case InputEventInjectionResult::TARGET_MISMATCH:
4893 ALOGV("Asynchronous input event injection target mismatch.");
4894 break;
4895 case InputEventInjectionResult::FAILED:
4896 ALOGW("Asynchronous input event injection failed.");
4897 break;
4898 case InputEventInjectionResult::TIMED_OUT:
4899 ALOGW("Asynchronous input event injection timed out.");
4900 break;
4901 case InputEventInjectionResult::PENDING:
4902 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4903 break;
4904 }
4905 }
4906
4907 injectionState.injectionResult = injectionResult;
4908 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004909}
4910
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004911void InputDispatcher::transformMotionEntryForInjectionLocked(
4912 MotionEntry& entry, const ui::Transform& injectedTransform) const {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004913 // Input injection works in the logical display coordinate space, but the input pipeline works
4914 // display space, so we need to transform the injected events accordingly.
4915 const auto it = mDisplayInfos.find(entry.displayId);
4916 if (it == mDisplayInfos.end()) return;
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004917 const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004918
Prabir Pradhand9a2ebe2022-07-20 19:25:13 +00004919 if (entry.xCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
4920 entry.yCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
4921 const vec2 cursor =
4922 MotionEvent::calculateTransformedXY(entry.source, transformToDisplay,
4923 {entry.xCursorPosition, entry.yCursorPosition});
4924 entry.xCursorPosition = cursor.x;
4925 entry.yCursorPosition = cursor.y;
4926 }
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004927 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
Prabir Pradhan8e6ce222022-02-24 09:08:54 -08004928 entry.pointerCoords[i] =
4929 MotionEvent::calculateTransformedCoords(entry.source, transformToDisplay,
4930 entry.pointerCoords[i]);
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004931 }
4932}
4933
Prabir Pradhan24047542023-11-02 17:14:59 +00004934void InputDispatcher::incrementPendingForegroundDispatches(const EventEntry& entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004935 if (entry.injectionState) {
4936 entry.injectionState->pendingForegroundDispatches += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004937 }
4938}
4939
Prabir Pradhan24047542023-11-02 17:14:59 +00004940void InputDispatcher::decrementPendingForegroundDispatches(const EventEntry& entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004941 if (entry.injectionState) {
4942 entry.injectionState->pendingForegroundDispatches -= 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004943
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004944 if (entry.injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004945 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004946 }
4947 }
4948}
4949
chaviw98318de2021-05-19 16:45:23 -05004950const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004951 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004952 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004953 auto it = mWindowHandlesByDisplay.find(displayId);
4954 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004955}
4956
chaviw98318de2021-05-19 16:45:23 -05004957sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
Prabir Pradhan16463382023-10-12 23:03:19 +00004958 const sp<IBinder>& windowHandleToken, std::optional<int32_t> displayId) const {
arthurhungbe737672020-06-24 12:29:21 +08004959 if (windowHandleToken == nullptr) {
4960 return nullptr;
4961 }
4962
Prabir Pradhan16463382023-10-12 23:03:19 +00004963 if (!displayId) {
4964 // Look through all displays.
4965 for (auto& it : mWindowHandlesByDisplay) {
4966 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4967 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
4968 if (windowHandle->getToken() == windowHandleToken) {
4969 return windowHandle;
4970 }
Arthur Hungb92218b2018-08-14 12:00:21 +08004971 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004972 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07004973 return nullptr;
4974 }
4975
Prabir Pradhan16463382023-10-12 23:03:19 +00004976 // Only look through the requested display.
4977 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(*displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004978 if (windowHandle->getToken() == windowHandleToken) {
4979 return windowHandle;
4980 }
4981 }
4982 return nullptr;
4983}
4984
chaviw98318de2021-05-19 16:45:23 -05004985sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4986 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004987 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004988 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4989 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004990 if (handle->getId() == windowHandle->getId() &&
4991 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004992 if (windowHandle->getInfo()->displayId != it.first) {
4993 ALOGE("Found window %s in display %" PRId32
4994 ", but it should belong to display %" PRId32,
4995 windowHandle->getName().c_str(), it.first,
4996 windowHandle->getInfo()->displayId);
4997 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004998 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004999 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005000 }
5001 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005002 return nullptr;
5003}
5004
chaviw98318de2021-05-19 16:45:23 -05005005sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005006 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
5007 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005008}
5009
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00005010ui::Transform InputDispatcher::getTransformLocked(int32_t displayId) const {
5011 auto displayInfoIt = mDisplayInfos.find(displayId);
5012 return displayInfoIt != mDisplayInfos.end() ? displayInfoIt->second.transform
5013 : kIdentityTransform;
5014}
5015
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005016bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& window,
5017 const MotionEntry& motionEntry) const {
5018 const WindowInfo& info = *window->getInfo();
5019
5020 // Skip spy window targets that are not valid for targeted injection.
5021 if (const auto err = verifyTargetedInjection(window, motionEntry); err) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005022 return false;
5023 }
5024
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005025 if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
5026 ALOGI("Not sending touch event to %s because it is paused", window->getName().c_str());
5027 return false;
5028 }
5029
5030 if (info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL)) {
5031 ALOGW("Not sending touch gesture to %s because it has config NO_INPUT_CHANNEL",
5032 window->getName().c_str());
5033 return false;
5034 }
5035
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005036 std::shared_ptr<Connection> connection = getConnectionLocked(window->getToken());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005037 if (connection == nullptr) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005038 ALOGW("Not sending touch to %s because there's no corresponding connection",
5039 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005040 return false;
5041 }
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005042
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005043 if (!connection->responsive) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005044 ALOGW("Not sending touch to %s because it is not responsive", window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005045 return false;
5046 }
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005047
5048 // Drop events that can't be trusted due to occlusion
5049 const auto [x, y] = resolveTouchedPosition(motionEntry);
5050 TouchOcclusionInfo occlusionInfo = computeTouchOcclusionInfoLocked(window, x, y);
5051 if (!isTouchTrustedLocked(occlusionInfo)) {
5052 if (DEBUG_TOUCH_OCCLUSION) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00005053 ALOGD("Stack of obscuring windows during untrusted touch (%.1f, %.1f):", x, y);
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005054 for (const auto& log : occlusionInfo.debugInfo) {
5055 ALOGD("%s", log.c_str());
5056 }
5057 }
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00005058 ALOGW("Dropping untrusted touch event due to %s/%s", occlusionInfo.obscuringPackage.c_str(),
5059 occlusionInfo.obscuringUid.toString().c_str());
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005060 return false;
5061 }
5062
5063 // Drop touch events if requested by input feature
5064 if (shouldDropInput(motionEntry, window)) {
5065 return false;
5066 }
5067
Siarhei Vishniakouf77f60a2023-10-23 17:26:05 -07005068 // Ignore touches if stylus is down anywhere on screen
5069 if (info.inputConfig.test(WindowInfo::InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH) &&
5070 isStylusActiveInDisplay(info.displayId, mTouchStatesByDisplay)) {
5071 LOG(INFO) << "Dropping touch from " << window->getName() << " because stylus is active";
5072 return false;
5073 }
5074
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005075 return true;
5076}
5077
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005078std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
5079 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005080 auto connectionIt = mConnectionsByToken.find(token);
5081 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07005082 return nullptr;
5083 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005084 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07005085}
5086
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005087void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05005088 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
5089 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005090 // Remove all handles on a display if there are no windows left.
5091 mWindowHandlesByDisplay.erase(displayId);
5092 return;
5093 }
5094
5095 // Since we compare the pointer of input window handles across window updates, we need
5096 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05005097 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
5098 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
5099 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07005100 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005101 }
5102
chaviw98318de2021-05-19 16:45:23 -05005103 std::vector<sp<WindowInfoHandle>> newHandles;
5104 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05005105 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005106 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005107 const bool noInputChannel =
Prabir Pradhan51e7db02022-02-07 06:02:57 -08005108 info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005109 const bool canReceiveInput =
5110 !info->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) ||
5111 !info->inputConfig.test(WindowInfo::InputConfig::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005112 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07005113 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005114 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07005115 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005116 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005117 }
5118
5119 if (info->displayId != displayId) {
5120 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
5121 handle->getName().c_str(), displayId, info->displayId);
5122 continue;
5123 }
5124
Robert Carredd13602020-04-13 17:24:34 -07005125 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
5126 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05005127 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005128 oldHandle->updateFrom(handle);
5129 newHandles.push_back(oldHandle);
5130 } else {
5131 newHandles.push_back(handle);
5132 }
5133 }
5134
5135 // Insert or replace
5136 mWindowHandlesByDisplay[displayId] = newHandles;
5137}
5138
Arthur Hungb92218b2018-08-14 12:00:21 +08005139/**
5140 * Called from InputManagerService, update window handle list by displayId that can receive input.
5141 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
5142 * If set an empty list, remove all handles from the specific display.
5143 * For focused handle, check if need to change and send a cancel event to previous one.
5144 * For removed handle, check if need to send a cancel event if already in touch.
5145 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00005146void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05005147 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005148 if (DEBUG_FOCUS) {
5149 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05005150 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005151 windowList += iwh->getName() + " ";
5152 }
Siarhei Vishniakou366fb5b2023-12-06 11:23:41 -08005153 LOG(INFO) << "setInputWindows displayId=" << displayId << " " << windowList;
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005154 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005155
Prabir Pradhand65552b2021-10-07 11:23:50 -07005156 // Check preconditions for new input windows
chaviw98318de2021-05-19 16:45:23 -05005157 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07005158 const WindowInfo& info = *window->getInfo();
5159
5160 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
Prabir Pradhan51e7db02022-02-07 06:02:57 -08005161 const bool noInputWindow = info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005162 if (noInputWindow && window->getToken() != nullptr) {
5163 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
5164 window->getName().c_str());
5165 window->releaseChannel();
5166 }
Prabir Pradhand65552b2021-10-07 11:23:50 -07005167
Prabir Pradhan5c85e052021-12-22 02:27:12 -08005168 // Ensure all spy windows are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005169 LOG_ALWAYS_FATAL_IF(info.isSpy() &&
5170 !info.inputConfig.test(
5171 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhan5c85e052021-12-22 02:27:12 -08005172 "%s has feature SPY, but is not a trusted overlay.",
5173 window->getName().c_str());
5174
Prabir Pradhand65552b2021-10-07 11:23:50 -07005175 // Ensure all stylus interceptors are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005176 LOG_ALWAYS_FATAL_IF(info.interceptsStylus() &&
5177 !info.inputConfig.test(
5178 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhand65552b2021-10-07 11:23:50 -07005179 "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
5180 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005181 }
5182
Arthur Hung72d8dc32020-03-28 00:48:39 +00005183 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05005184 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005185
chaviw98318de2021-05-19 16:45:23 -05005186 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005187
chaviw98318de2021-05-19 16:45:23 -05005188 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00005189
Vishnu Nairc519ff72021-01-21 08:23:08 -08005190 std::optional<FocusResolver::FocusChanges> changes =
5191 mFocusResolver.setInputWindows(displayId, windowHandles);
5192 if (changes) {
5193 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00005194 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005195
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005196 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5197 mTouchStatesByDisplay.find(displayId);
5198 if (stateIt != mTouchStatesByDisplay.end()) {
5199 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00005200 for (size_t i = 0; i < state.windows.size();) {
5201 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005202 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07005203 LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName()
5204 << " in display %" << displayId;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005205 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00005206 getInputChannelLocked(touchedWindow.windowHandle->getToken());
5207 if (touchedInputChannel != nullptr) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00005208 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Arthur Hung72d8dc32020-03-28 00:48:39 +00005209 "touched window was removed");
5210 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005211 // Since we are about to drop the touch, cancel the events for the wallpaper as
5212 // well.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005213 if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005214 touchedWindow.windowHandle->getInfo()->inputConfig.test(
5215 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005216 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
Arthur Hungc539dbb2022-12-08 07:45:36 +00005217 synthesizeCancelationEventsForWindowLocked(wallpaper, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005218 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005219 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005220 state.windows.erase(state.windows.begin() + i);
5221 } else {
5222 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005223 }
5224 }
arthurhungb89ccb02020-12-30 16:19:01 +08005225
arthurhung6d4bed92021-03-17 11:59:33 +08005226 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08005227 // could just clear the state here.
Arthur Hung3915c1f2022-05-31 07:17:17 +00005228 if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId &&
arthurhung6d4bed92021-03-17 11:59:33 +08005229 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08005230 windowHandles.end()) {
Arthur Hung3915c1f2022-05-31 07:17:17 +00005231 ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str());
5232 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08005233 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08005234 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005235 }
Arthur Hung25e2af12020-03-26 12:58:37 +00005236
Arthur Hung72d8dc32020-03-28 00:48:39 +00005237 // Release information for windows that are no longer present.
5238 // This ensures that unused input channels are released promptly.
5239 // Otherwise, they might stick around until the window handle is destroyed
5240 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05005241 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005242 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00005243 if (DEBUG_FOCUS) {
5244 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00005245 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005246 oldWindowHandle->releaseChannel();
Arthur Hung25e2af12020-03-26 12:58:37 +00005247 }
chaviw291d88a2019-02-14 10:33:58 -08005248 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005249}
5250
5251void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07005252 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005253 if (DEBUG_FOCUS) {
5254 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
5255 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
5256 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005257 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005258 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07005259 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005260 } // release lock
5261
5262 // Wake up poll loop since it may need to make new input dispatching choices.
5263 mLooper->wake();
5264}
5265
Vishnu Nair599f1412021-06-21 10:39:58 -07005266void InputDispatcher::setFocusedApplicationLocked(
5267 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
5268 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
5269 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
5270
5271 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
5272 return; // This application is already focused. No need to wake up or change anything.
5273 }
5274
5275 // Set the new application handle.
5276 if (inputApplicationHandle != nullptr) {
5277 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
5278 } else {
5279 mFocusedApplicationHandlesByDisplay.erase(displayId);
5280 }
5281
5282 // No matter what the old focused application was, stop waiting on it because it is
5283 // no longer focused.
5284 resetNoFocusedWindowTimeoutLocked();
5285}
5286
Tiger Huang721e26f2018-07-24 22:26:19 +08005287/**
5288 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
5289 * the display not specified.
5290 *
5291 * We track any unreleased events for each window. If a window loses the ability to receive the
5292 * released event, we will send a cancel event to it. So when the focused display is changed, we
5293 * cancel all the unreleased display-unspecified events for the focused window on the old focused
5294 * display. The display-specified events won't be affected.
5295 */
5296void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005297 if (DEBUG_FOCUS) {
5298 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
5299 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005300 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005301 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08005302
5303 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005304 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08005305 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005306 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005307 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07005308 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08005309 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005310 CancelationOptions
Michael Wrightfb04fd52022-11-24 22:31:11 +00005311 options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005312 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005313 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08005314 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
5315 }
5316 }
5317 mFocusedDisplayId = displayId;
5318
Chris Ye3c2d6f52020-08-09 10:39:48 -07005319 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08005320 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00005321 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08005322
Vishnu Nairad321cd2020-08-20 16:40:21 -07005323 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08005324 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005325 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005326 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08005327 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08005328 }
5329 }
5330 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005331 } // release lock
5332
5333 // Wake up poll loop since it may need to make new input dispatching choices.
5334 mLooper->wake();
5335}
5336
Michael Wrightd02c5b62014-02-10 15:10:22 -08005337void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005338 if (DEBUG_FOCUS) {
5339 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
5340 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005341
5342 bool changed;
5343 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005344 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005345
5346 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
5347 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005348 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005349 }
5350
5351 if (mDispatchEnabled && !enabled) {
5352 resetAndDropEverythingLocked("dispatcher is being disabled");
5353 }
5354
5355 mDispatchEnabled = enabled;
5356 mDispatchFrozen = frozen;
5357 changed = true;
5358 } else {
5359 changed = false;
5360 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005361 } // release lock
5362
5363 if (changed) {
5364 // Wake up poll loop since it may need to make new input dispatching choices.
5365 mLooper->wake();
5366 }
5367}
5368
5369void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005370 if (DEBUG_FOCUS) {
5371 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
5372 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005373
5374 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005375 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005376
5377 if (mInputFilterEnabled == enabled) {
5378 return;
5379 }
5380
5381 mInputFilterEnabled = enabled;
5382 resetAndDropEverythingLocked("input filter is being enabled or disabled");
5383 } // release lock
5384
5385 // Wake up poll loop since there might be work to do to drop everything.
5386 mLooper->wake();
5387}
5388
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005389bool InputDispatcher::setInTouchMode(bool inTouchMode, gui::Pid pid, gui::Uid uid,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00005390 bool hasPermission, int32_t displayId) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00005391 bool needWake = false;
5392 {
5393 std::scoped_lock lock(mLock);
Antonio Kantek15beb512022-06-13 22:35:41 +00005394 ALOGD_IF(DEBUG_TOUCH_MODE,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005395 "Request to change touch mode to %s (calling pid=%s, uid=%s, "
Antonio Kantek15beb512022-06-13 22:35:41 +00005396 "hasPermission=%s, target displayId=%d, mTouchModePerDisplay[displayId]=%s)",
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005397 toString(inTouchMode), pid.toString().c_str(), uid.toString().c_str(),
5398 toString(hasPermission), displayId,
Antonio Kantek15beb512022-06-13 22:35:41 +00005399 mTouchModePerDisplay.count(displayId) == 0
5400 ? "not set"
5401 : std::to_string(mTouchModePerDisplay[displayId]).c_str());
5402
Antonio Kantek15beb512022-06-13 22:35:41 +00005403 auto touchModeIt = mTouchModePerDisplay.find(displayId);
5404 if (touchModeIt != mTouchModePerDisplay.end() && touchModeIt->second == inTouchMode) {
Antonio Kantekea47acb2021-12-23 12:41:25 -08005405 return false;
Antonio Kantekf16f2832021-09-28 04:39:20 +00005406 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005407 if (!hasPermission) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005408 if (!focusedWindowIsOwnedByLocked(pid, uid) &&
5409 !recentWindowsAreOwnedByLocked(pid, uid)) {
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005410 ALOGD("Touch mode switch rejected, caller (pid=%s, uid=%s) doesn't own the focused "
Antonio Kantek48710e42022-03-24 14:19:30 -07005411 "window nor none of the previously interacted window",
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005412 pid.toString().c_str(), uid.toString().c_str());
Antonio Kantekea47acb2021-12-23 12:41:25 -08005413 return false;
5414 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00005415 }
Antonio Kantek15beb512022-06-13 22:35:41 +00005416 mTouchModePerDisplay[displayId] = inTouchMode;
5417 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode,
5418 displayId);
Antonio Kantekf16f2832021-09-28 04:39:20 +00005419 needWake = enqueueInboundEventLocked(std::move(entry));
5420 } // release lock
5421
5422 if (needWake) {
5423 mLooper->wake();
5424 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005425 return true;
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08005426}
5427
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005428bool InputDispatcher::focusedWindowIsOwnedByLocked(gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005429 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
5430 if (focusedToken == nullptr) {
5431 return false;
5432 }
5433 sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken);
5434 return isWindowOwnedBy(windowHandle, pid, uid);
5435}
5436
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005437bool InputDispatcher::recentWindowsAreOwnedByLocked(gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005438 return std::find_if(mInteractionConnectionTokens.begin(), mInteractionConnectionTokens.end(),
5439 [&](const sp<IBinder>& connectionToken) REQUIRES(mLock) {
5440 const sp<WindowInfoHandle> windowHandle =
5441 getWindowHandleLocked(connectionToken);
5442 return isWindowOwnedBy(windowHandle, pid, uid);
5443 }) != mInteractionConnectionTokens.end();
5444}
5445
Bernardo Rufinoea97d182020-08-19 14:43:14 +01005446void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
5447 if (opacity < 0 || opacity > 1) {
5448 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
5449 return;
5450 }
5451
5452 std::scoped_lock lock(mLock);
5453 mMaximumObscuringOpacityForTouch = opacity;
5454}
5455
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005456std::tuple<TouchState*, TouchedWindow*, int32_t /*displayId*/>
5457InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) {
Arthur Hungabbb9d82021-09-01 14:52:30 +00005458 for (auto& [displayId, state] : mTouchStatesByDisplay) {
5459 for (TouchedWindow& w : state.windows) {
5460 if (w.windowHandle->getToken() == token) {
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005461 return std::make_tuple(&state, &w, displayId);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005462 }
5463 }
5464 }
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005465 return std::make_tuple(nullptr, nullptr, ADISPLAY_ID_DEFAULT);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005466}
5467
arthurhungb89ccb02020-12-30 16:19:01 +08005468bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5469 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08005470 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005471 if (DEBUG_FOCUS) {
5472 ALOGD("Trivial transfer to same window.");
5473 }
chaviwfbe5d9c2018-12-26 12:23:37 -08005474 return true;
5475 }
5476
Michael Wrightd02c5b62014-02-10 15:10:22 -08005477 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005478 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005479
Arthur Hungabbb9d82021-09-01 14:52:30 +00005480 // Find the target touch state and touched window by fromToken.
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005481 auto [state, touchedWindow, displayId] = findTouchStateWindowAndDisplayLocked(fromToken);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005482
Arthur Hungabbb9d82021-09-01 14:52:30 +00005483 if (state == nullptr || touchedWindow == nullptr) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005484 ALOGD("Touch transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005485 return false;
5486 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005487 std::set<int32_t> deviceIds = touchedWindow->getTouchingDeviceIds();
5488 if (deviceIds.size() != 1) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07005489 LOG(INFO) << "Can't transfer touch. Currently touching devices: " << dumpSet(deviceIds)
5490 << " for window: " << touchedWindow->dump();
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005491 return false;
5492 }
5493 const int32_t deviceId = *deviceIds.begin();
Arthur Hungabbb9d82021-09-01 14:52:30 +00005494
Arthur Hungabbb9d82021-09-01 14:52:30 +00005495 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
5496 if (toWindowHandle == nullptr) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005497 ALOGW("Cannot transfer touch because to window not found.");
Arthur Hungabbb9d82021-09-01 14:52:30 +00005498 return false;
5499 }
5500
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005501 if (DEBUG_FOCUS) {
5502 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00005503 touchedWindow->windowHandle->getName().c_str(),
5504 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005505 }
5506
Arthur Hungabbb9d82021-09-01 14:52:30 +00005507 // Erase old window.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005508 ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags;
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08005509 std::vector<PointerProperties> pointers = touchedWindow->getTouchingPointers(deviceId);
Arthur Hungc539dbb2022-12-08 07:45:36 +00005510 sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
Arthur Hungabbb9d82021-09-01 14:52:30 +00005511 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005512
Arthur Hungabbb9d82021-09-01 14:52:30 +00005513 // Add new window.
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00005514 nsecs_t downTimeInTarget = now();
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005515 ftl::Flags<InputTarget::Flags> newTargetFlags =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00005516 oldTargetFlags & (InputTarget::Flags::SPLIT);
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005517 if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005518 newTargetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005519 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00005520 state->addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08005521 deviceId, pointers, downTimeInTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005522
Arthur Hungabbb9d82021-09-01 14:52:30 +00005523 // Store the dragging window.
5524 if (isDragDrop) {
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08005525 if (pointers.size() != 1) {
Arthur Hungb75c2aa2022-07-15 09:35:36 +00005526 ALOGW("The drag and drop cannot be started when there is no pointer or more than 1"
5527 " pointer on the window.");
Arthur Hung54745652022-04-20 07:17:41 +00005528 return false;
5529 }
Arthur Hungb75c2aa2022-07-15 09:35:36 +00005530 // Track the pointer id for drag window and generate the drag state.
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08005531 const size_t id = pointers.begin()->id;
Arthur Hung54745652022-04-20 07:17:41 +00005532 mDragState = std::make_unique<DragState>(toWindowHandle, id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005533 }
5534
Arthur Hungabbb9d82021-09-01 14:52:30 +00005535 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005536 std::shared_ptr<Connection> fromConnection = getConnectionLocked(fromToken);
5537 std::shared_ptr<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005538 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005539 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005540 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5541 "transferring touch from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005542 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Arthur Hungc539dbb2022-12-08 07:45:36 +00005543 synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection,
5544 newTargetFlags);
5545
5546 // Check if the wallpaper window should deliver the corresponding event.
5547 transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08005548 *state, deviceId, pointers);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005549 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005550 } // release lock
5551
5552 // Wake up poll loop since it may need to make new input dispatching choices.
5553 mLooper->wake();
5554 return true;
5555}
5556
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005557/**
5558 * Get the touched foreground window on the given display.
5559 * Return null if there are no windows touched on that display, or if more than one foreground
5560 * window is being touched.
5561 */
5562sp<WindowInfoHandle> InputDispatcher::findTouchedForegroundWindowLocked(int32_t displayId) const {
5563 auto stateIt = mTouchStatesByDisplay.find(displayId);
5564 if (stateIt == mTouchStatesByDisplay.end()) {
5565 ALOGI("No touch state on display %" PRId32, displayId);
5566 return nullptr;
5567 }
5568
5569 const TouchState& state = stateIt->second;
5570 sp<WindowInfoHandle> touchedForegroundWindow;
5571 // If multiple foreground windows are touched, return nullptr
5572 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005573 if (window.targetFlags.test(InputTarget::Flags::FOREGROUND)) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005574 if (touchedForegroundWindow != nullptr) {
5575 ALOGI("Two or more foreground windows: %s and %s",
5576 touchedForegroundWindow->getName().c_str(),
5577 window.windowHandle->getName().c_str());
5578 return nullptr;
5579 }
5580 touchedForegroundWindow = window.windowHandle;
5581 }
5582 }
5583 return touchedForegroundWindow;
5584}
5585
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005586// Binder call
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005587bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken, int32_t displayId) {
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005588 sp<IBinder> fromToken;
5589 { // acquire lock
5590 std::scoped_lock _l(mLock);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005591 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005592 if (toWindowHandle == nullptr) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005593 ALOGW("Could not find window associated with token=%p on display %" PRId32,
5594 destChannelToken.get(), displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005595 return false;
5596 }
5597
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005598 sp<WindowInfoHandle> from = findTouchedForegroundWindowLocked(displayId);
5599 if (from == nullptr) {
5600 ALOGE("Could not find a source window in %s for %p", __func__, destChannelToken.get());
5601 return false;
5602 }
5603
5604 fromToken = from->getToken();
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005605 } // release lock
5606
5607 return transferTouchFocus(fromToken, destChannelToken);
5608}
5609
Michael Wrightd02c5b62014-02-10 15:10:22 -08005610void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005611 if (DEBUG_FOCUS) {
5612 ALOGD("Resetting and dropping all events (%s).", reason);
5613 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005614
Michael Wrightfb04fd52022-11-24 22:31:11 +00005615 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005616 synthesizeCancelationEventsForAllConnectionsLocked(options);
5617
5618 resetKeyRepeatLocked();
5619 releasePendingEventLocked();
5620 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005621 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005622
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005623 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005624 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005625}
5626
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005627void InputDispatcher::logDispatchStateLocked() const {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005628 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005629 dumpDispatchStateLocked(dump);
5630
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005631 std::istringstream stream(dump);
5632 std::string line;
5633
5634 while (std::getline(stream, line, '\n')) {
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07005635 ALOGI("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005636 }
5637}
5638
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005639std::string InputDispatcher::dumpPointerCaptureStateLocked() const {
Prabir Pradhan99987712020-11-10 18:43:05 -08005640 std::string dump;
5641
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005642 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5643 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005644
5645 std::string windowName = "None";
5646 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005647 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005648 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5649 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5650 : "token has capture without window";
5651 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005652 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005653
5654 return dump;
5655}
5656
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005657void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005658 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5659 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5660 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005661 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005662
Tiger Huang721e26f2018-07-24 22:26:19 +08005663 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5664 dump += StringPrintf(INDENT "FocusedApplications:\n");
5665 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5666 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005667 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005668 const std::chrono::duration timeout =
5669 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005670 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005671 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005672 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005673 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005674 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005675 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005676 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005677
Vishnu Nairc519ff72021-01-21 08:23:08 -08005678 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005679 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005680
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005681 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005682 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005683 for (const auto& [displayId, state] : mTouchStatesByDisplay) {
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -08005684 std::string touchStateDump = addLinePrefix(state.dump(), INDENT2);
5685 dump += INDENT2 + std::to_string(displayId) + " : " + touchStateDump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005686 }
5687 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005688 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005689 }
5690
arthurhung6d4bed92021-03-17 11:59:33 +08005691 if (mDragState) {
5692 dump += StringPrintf(INDENT "DragState:\n");
5693 mDragState->dump(dump, INDENT2);
5694 }
5695
Arthur Hungb92218b2018-08-14 12:00:21 +08005696 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005697 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5698 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5699 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5700 const auto& displayInfo = it->second;
5701 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5702 displayInfo.logicalHeight);
5703 displayInfo.transform.dump(dump, "transform", INDENT4);
5704 } else {
5705 dump += INDENT2 "No DisplayInfo found!\n";
5706 }
5707
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005708 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005709 dump += INDENT2 "Windows:\n";
5710 for (size_t i = 0; i < windowHandles.size(); i++) {
Siarhei Vishniakou366fb5b2023-12-06 11:23:41 -08005711 dump += StringPrintf(INDENT3 "%zu: %s", i,
5712 streamableToString(*windowHandles[i]).c_str());
Arthur Hungb92218b2018-08-14 12:00:21 +08005713 }
5714 } else {
5715 dump += INDENT2 "Windows: <none>\n";
5716 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005717 }
5718 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005719 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005720 }
5721
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005722 if (!mGlobalMonitorsByDisplay.empty()) {
5723 for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
5724 dump += StringPrintf(INDENT "Global monitors on display %d:\n", displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00005725 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005726 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005727 } else {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005728 dump += INDENT "Global Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005729 }
5730
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005731 const nsecs_t currentTime = now();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005732
5733 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005734 if (!mRecentQueue.empty()) {
5735 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Prabir Pradhan24047542023-11-02 17:14:59 +00005736 for (const std::shared_ptr<const EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005737 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005738 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005739 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005740 }
5741 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005742 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005743 }
5744
5745 // Dump event currently being dispatched.
5746 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005747 dump += INDENT "PendingEvent:\n";
5748 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005749 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005750 dump += StringPrintf(", age=%" PRId64 "ms\n",
5751 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005752 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005753 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005754 }
5755
5756 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005757 if (!mInboundQueue.empty()) {
5758 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Prabir Pradhan24047542023-11-02 17:14:59 +00005759 for (const std::shared_ptr<const EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005760 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005761 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005762 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005763 }
5764 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005765 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005766 }
5767
Prabir Pradhancef936d2021-07-21 16:17:52 +00005768 if (!mCommandQueue.empty()) {
5769 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5770 } else {
5771 dump += INDENT "CommandQueue: <empty>\n";
5772 }
5773
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005774 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005775 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005776 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005777 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005778 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005779 connection->inputChannel->getFd().get(),
5780 connection->getInputChannelName().c_str(),
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005781 connection->getWindowName().c_str(),
5782 ftl::enum_string(connection->status).c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005783 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005784
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005785 if (!connection->outboundQueue.empty()) {
5786 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5787 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005788 dump += dumpQueue(connection->outboundQueue, currentTime);
5789
Michael Wrightd02c5b62014-02-10 15:10:22 -08005790 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005791 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005792 }
5793
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005794 if (!connection->waitQueue.empty()) {
5795 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5796 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005797 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005798 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005799 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005800 }
Siarhei Vishniakou366fb5b2023-12-06 11:23:41 -08005801 std::string inputStateDump = streamableToString(connection->inputState);
5802 if (!inputStateDump.empty()) {
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -07005803 dump += INDENT3 "InputState: ";
Siarhei Vishniakou366fb5b2023-12-06 11:23:41 -08005804 dump += inputStateDump + "\n";
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -07005805 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005806 }
5807 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005808 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005809 }
5810
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07005811 dump += "input_flags::remove_app_switch_drops() = ";
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07005812 dump += toString(REMOVE_APP_SWITCH_DROPS);
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07005813 dump += "\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005814 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005815 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5816 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005817 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005818 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005819 }
5820
Antonio Kantek15beb512022-06-13 22:35:41 +00005821 if (!mTouchModePerDisplay.empty()) {
5822 dump += INDENT "TouchModePerDisplay:\n";
5823 for (const auto& [displayId, touchMode] : mTouchModePerDisplay) {
5824 dump += StringPrintf(INDENT2 "Display: %" PRId32 " TouchMode: %s\n", displayId,
5825 std::to_string(touchMode).c_str());
5826 }
5827 } else {
5828 dump += INDENT "TouchModePerDisplay: <none>\n";
5829 }
5830
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005831 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005832 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5833 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5834 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005835 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005836 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005837}
5838
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005839void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00005840 const size_t numMonitors = monitors.size();
5841 for (size_t i = 0; i < numMonitors; i++) {
5842 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005843 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005844 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5845 dump += "\n";
5846 }
5847}
5848
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005849class LooperEventCallback : public LooperCallback {
5850public:
5851 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5852 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5853
5854private:
5855 std::function<int(int events)> mCallback;
5856};
5857
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005858Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005859 if (DEBUG_CHANNEL_CREATION) {
5860 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5861 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005862
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005863 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005864 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005865 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005866
5867 if (result) {
5868 return base::Error(result) << "Failed to open input channel pair with name " << name;
5869 }
5870
Michael Wrightd02c5b62014-02-10 15:10:22 -08005871 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005872 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005873 const sp<IBinder>& token = serverChannel->getConnectionToken();
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005874 auto&& fd = serverChannel->getFd();
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005875 std::shared_ptr<Connection> connection =
5876 std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/false,
5877 mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005878
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005879 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5880 ALOGE("Created a new connection, but the token %p is already known", token.get());
5881 }
5882 mConnectionsByToken.emplace(token, connection);
5883
5884 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5885 this, std::placeholders::_1, token);
5886
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005887 mLooper->addFd(fd.get(), 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005888 nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005889 } // release lock
5890
5891 // Wake the looper because some connections have changed.
5892 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005893 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005894}
5895
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005896Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005897 const std::string& name,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005898 gui::Pid pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005899 std::shared_ptr<InputChannel> serverChannel;
5900 std::unique_ptr<InputChannel> clientChannel;
5901 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5902 if (result) {
5903 return base::Error(result) << "Failed to open input channel pair with name " << name;
5904 }
5905
Michael Wright3dd60e22019-03-27 22:06:44 +00005906 { // acquire lock
5907 std::scoped_lock _l(mLock);
5908
5909 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005910 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5911 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005912 }
5913
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005914 std::shared_ptr<Connection> connection =
5915 std::make_shared<Connection>(serverChannel, /*monitor=*/true, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005916 const sp<IBinder>& token = serverChannel->getConnectionToken();
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005917 auto&& fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005918
5919 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5920 ALOGE("Created a new connection, but the token %p is already known", token.get());
5921 }
5922 mConnectionsByToken.emplace(token, connection);
5923 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5924 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005925
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005926 mGlobalMonitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005927
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005928 mLooper->addFd(fd.get(), 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005929 nullptr);
Michael Wright3dd60e22019-03-27 22:06:44 +00005930 }
Garfield Tan15601662020-09-22 15:32:38 -07005931
Michael Wright3dd60e22019-03-27 22:06:44 +00005932 // Wake the looper because some connections have changed.
5933 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005934 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005935}
5936
Garfield Tan15601662020-09-22 15:32:38 -07005937status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005938 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005939 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005940
Harry Cutts33476232023-01-30 19:57:29 +00005941 status_t status = removeInputChannelLocked(connectionToken, /*notify=*/false);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005942 if (status) {
5943 return status;
5944 }
5945 } // release lock
5946
5947 // Wake the poll loop because removing the connection may have changed the current
5948 // synchronization state.
5949 mLooper->wake();
5950 return OK;
5951}
5952
Garfield Tan15601662020-09-22 15:32:38 -07005953status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5954 bool notify) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005955 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005956 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005957 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005958 return BAD_VALUE;
5959 }
5960
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005961 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005962
Michael Wrightd02c5b62014-02-10 15:10:22 -08005963 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005964 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005965 }
5966
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005967 mLooper->removeFd(connection->inputChannel->getFd().get());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005968
5969 nsecs_t currentTime = now();
5970 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5971
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005972 connection->status = Connection::Status::ZOMBIE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005973 return OK;
5974}
5975
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005976void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005977 for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
5978 auto& [displayId, monitors] = *it;
5979 std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
5980 return monitor.inputChannel->getConnectionToken() == connectionToken;
5981 });
Michael Wright3dd60e22019-03-27 22:06:44 +00005982
Michael Wright3dd60e22019-03-27 22:06:44 +00005983 if (monitors.empty()) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005984 it = mGlobalMonitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005985 } else {
5986 ++it;
5987 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005988 }
5989}
5990
Michael Wright3dd60e22019-03-27 22:06:44 +00005991status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005992 std::scoped_lock _l(mLock);
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00005993 return pilferPointersLocked(token);
5994}
Michael Wright3dd60e22019-03-27 22:06:44 +00005995
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00005996status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005997 const std::shared_ptr<InputChannel> requestingChannel = getInputChannelLocked(token);
5998 if (!requestingChannel) {
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07005999 LOG(WARNING)
6000 << "Attempted to pilfer pointers from an un-registered channel or invalid token";
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006001 return BAD_VALUE;
Michael Wright3dd60e22019-03-27 22:06:44 +00006002 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006003
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07006004 auto [statePtr, windowPtr, displayId] = findTouchStateWindowAndDisplayLocked(token);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006005 if (statePtr == nullptr || windowPtr == nullptr) {
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006006 LOG(WARNING)
6007 << "Attempted to pilfer points from a channel without any on-going pointer streams."
6008 " Ignoring.";
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006009 return BAD_VALUE;
6010 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006011 std::set<int32_t> deviceIds = windowPtr->getTouchingDeviceIds();
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07006012 if (deviceIds.empty()) {
6013 LOG(WARNING) << "Can't pilfer: no touching devices in window: " << windowPtr->dump();
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006014 return BAD_VALUE;
6015 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006016
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006017 for (const DeviceId deviceId : deviceIds) {
6018 TouchState& state = *statePtr;
6019 TouchedWindow& window = *windowPtr;
6020 // Send cancel events to all the input channels we're stealing from.
6021 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6022 "input channel stole pointer stream");
6023 options.deviceId = deviceId;
6024 options.displayId = displayId;
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006025 std::vector<PointerProperties> pointers = window.getTouchingPointers(deviceId);
6026 std::bitset<MAX_POINTER_ID + 1> pointerIds = getPointerIds(pointers);
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006027 options.pointerIds = pointerIds;
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006028
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006029 std::string canceledWindows;
6030 for (const TouchedWindow& w : state.windows) {
6031 const std::shared_ptr<InputChannel> channel =
6032 getInputChannelLocked(w.windowHandle->getToken());
6033 if (channel != nullptr && channel->getConnectionToken() != token) {
6034 synthesizeCancelationEventsForInputChannelLocked(channel, options);
6035 canceledWindows += canceledWindows.empty() ? "[" : ", ";
6036 canceledWindows += channel->getName();
6037 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006038 }
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006039 canceledWindows += canceledWindows.empty() ? "[]" : "]";
6040 LOG(INFO) << "Channel " << requestingChannel->getName()
6041 << " is stealing input gesture for device " << deviceId << " from "
6042 << canceledWindows;
6043
6044 // Prevent the gesture from being sent to any other windows.
6045 // This only blocks relevant pointers to be sent to other windows
6046 window.addPilferingPointers(deviceId, pointerIds);
6047
6048 state.cancelPointersForWindowsExcept(deviceId, pointerIds, token);
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006049 }
Michael Wright3dd60e22019-03-27 22:06:44 +00006050 return OK;
6051}
6052
Prabir Pradhan99987712020-11-10 18:43:05 -08006053void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
6054 { // acquire lock
6055 std::scoped_lock _l(mLock);
6056 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05006057 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08006058 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
6059 windowHandle != nullptr ? windowHandle->getName().c_str()
6060 : "token without window");
6061 }
6062
Vishnu Nairc519ff72021-01-21 08:23:08 -08006063 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08006064 if (focusedToken != windowToken) {
6065 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
6066 enabled ? "enable" : "disable");
6067 return;
6068 }
6069
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006070 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006071 ALOGW("Ignoring request to %s Pointer Capture: "
6072 "window has %s requested pointer capture.",
6073 enabled ? "enable" : "disable", enabled ? "already" : "not");
6074 return;
6075 }
6076
Christine Franksb768bb42021-11-29 12:11:31 -08006077 if (enabled) {
6078 if (std::find(mIneligibleDisplaysForPointerCapture.begin(),
6079 mIneligibleDisplaysForPointerCapture.end(),
6080 mFocusedDisplayId) != mIneligibleDisplaysForPointerCapture.end()) {
6081 ALOGW("Ignoring request to enable Pointer Capture: display is not eligible");
6082 return;
6083 }
6084 }
6085
Prabir Pradhan99987712020-11-10 18:43:05 -08006086 setPointerCaptureLocked(enabled);
6087 } // release lock
6088
6089 // Wake the thread to process command entries.
6090 mLooper->wake();
6091}
6092
Christine Franksb768bb42021-11-29 12:11:31 -08006093void InputDispatcher::setDisplayEligibilityForPointerCapture(int32_t displayId, bool isEligible) {
6094 { // acquire lock
6095 std::scoped_lock _l(mLock);
6096 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
6097 if (!isEligible) {
6098 mIneligibleDisplaysForPointerCapture.push_back(displayId);
6099 }
6100 } // release lock
6101}
6102
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006103std::optional<gui::Pid> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006104 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00006105 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006106 if (monitor.inputChannel->getConnectionToken() == token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006107 return monitor.pid;
Michael Wright3dd60e22019-03-27 22:06:44 +00006108 }
6109 }
6110 }
6111 return std::nullopt;
6112}
6113
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006114std::shared_ptr<Connection> InputDispatcher::getConnectionLocked(
6115 const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07006116 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006117 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08006118 }
6119
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00006120 for (const auto& [token, connection] : mConnectionsByToken) {
6121 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006122 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006123 }
6124 }
Robert Carr4e670e52018-08-15 13:26:12 -07006125
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006126 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006127}
6128
Siarhei Vishniakouad991402020-10-28 11:40:09 -05006129std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006130 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakouad991402020-10-28 11:40:09 -05006131 if (connection == nullptr) {
6132 return "<nullptr>";
6133 }
6134 return connection->getInputChannelName();
6135}
6136
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006137void InputDispatcher::removeConnectionLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006138 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00006139 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07006140}
6141
Prabir Pradhancef936d2021-07-21 16:17:52 +00006142void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006143 const std::shared_ptr<Connection>& connection,
6144 uint32_t seq, bool handled,
6145 nsecs_t consumeTime) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006146 // Handle post-event policy actions.
Prabir Pradhan24047542023-11-02 17:14:59 +00006147 std::unique_ptr<const KeyEntry> fallbackKeyEntry;
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006148
6149 { // Start critical section
6150 auto dispatchEntryIt =
6151 std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6152 [seq](auto& e) { return e->seq == seq; });
6153 if (dispatchEntryIt == connection->waitQueue.end()) {
6154 return;
6155 }
6156
6157 DispatchEntry& dispatchEntry = **dispatchEntryIt;
6158
6159 const nsecs_t eventDuration = finishTime - dispatchEntry.deliveryTime;
6160 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
6161 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
6162 ns2ms(eventDuration), dispatchEntry.eventEntry->getDescription().c_str());
6163 }
6164 if (shouldReportFinishedEvent(dispatchEntry, *connection)) {
6165 mLatencyTracker.trackFinishedEvent(dispatchEntry.eventEntry->id,
6166 connection->inputChannel->getConnectionToken(),
6167 dispatchEntry.deliveryTime, consumeTime, finishTime);
6168 }
6169
6170 if (dispatchEntry.eventEntry->type == EventEntry::Type::KEY) {
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006171 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*(dispatchEntry.eventEntry));
6172 fallbackKeyEntry =
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006173 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006174 }
6175 } // End critical section: The -LockedInterruptable methods may have released the lock.
Prabir Pradhancef936d2021-07-21 16:17:52 +00006176
6177 // Dequeue the event and start the next cycle.
6178 // Because the lock might have been released, it is possible that the
6179 // contents of the wait queue to have been drained, so we need to double-check
6180 // a few things.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006181 auto entryIt = std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6182 [seq](auto& e) { return e->seq == seq; });
6183 if (entryIt != connection->waitQueue.end()) {
6184 std::unique_ptr<DispatchEntry> dispatchEntry = std::move(*entryIt);
6185 connection->waitQueue.erase(entryIt);
6186
Prabir Pradhancef936d2021-07-21 16:17:52 +00006187 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
6188 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
6189 if (!connection->responsive) {
6190 connection->responsive = isConnectionResponsive(*connection);
6191 if (connection->responsive) {
6192 // The connection was unresponsive, and now it's responsive.
6193 processConnectionResponsiveLocked(*connection);
6194 }
6195 }
6196 traceWaitQueueLength(*connection);
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006197 if (fallbackKeyEntry && connection->status == Connection::Status::NORMAL) {
6198 const InputTarget target{.inputChannel = connection->inputChannel,
6199 .flags = dispatchEntry->targetFlags};
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006200 enqueueDispatchEntryLocked(connection, std::move(fallbackKeyEntry), target);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006201 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006202 releaseDispatchEntry(std::move(dispatchEntry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00006203 }
6204
6205 // Start the next dispatch cycle for this connection.
6206 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006207}
6208
Prabir Pradhancef936d2021-07-21 16:17:52 +00006209void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
6210 const sp<IBinder>& newToken) {
6211 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
6212 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006213 mPolicy.notifyFocusChanged(oldToken, newToken);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006214 };
6215 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006216}
6217
Prabir Pradhancef936d2021-07-21 16:17:52 +00006218void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
6219 auto command = [this, token, x, y]() REQUIRES(mLock) {
6220 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006221 mPolicy.notifyDropWindow(token, x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006222 };
6223 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08006224}
6225
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006226void InputDispatcher::onAnrLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006227 if (connection == nullptr) {
6228 LOG_ALWAYS_FATAL("Caller must check for nullness");
6229 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006230 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
6231 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006232 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006233 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006234 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006235 return;
6236 }
6237 /**
6238 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
6239 * may not be the one that caused the timeout to occur. One possibility is that window timeout
6240 * has changed. This could cause newer entries to time out before the already dispatched
6241 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
6242 * processes the events linearly. So providing information about the oldest entry seems to be
6243 * most useful.
6244 */
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006245 DispatchEntry& oldestEntry = *connection->waitQueue.front();
6246 const nsecs_t currentWait = now() - oldestEntry.deliveryTime;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006247 std::string reason =
6248 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006249 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006250 ns2ms(currentWait),
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006251 oldestEntry.eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006252 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06006253 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006254
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006255 processConnectionUnresponsiveLocked(*connection, std::move(reason));
6256
6257 // Stop waking up for events on this connection, it is already unresponsive
6258 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006259}
6260
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05006261void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
6262 std::string reason =
6263 StringPrintf("%s does not have a focused window", application->getName().c_str());
6264 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006265
Yabin Cui8eb9c552023-06-08 18:05:07 +00006266 auto command = [this, app = std::move(application)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006267 scoped_unlock unlock(mLock);
Yabin Cuiced952f2023-06-09 21:12:51 +00006268 mPolicy.notifyNoFocusedWindowAnr(app);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006269 };
6270 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00006271}
6272
chaviw98318de2021-05-19 16:45:23 -05006273void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006274 const std::string& reason) {
6275 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
6276 updateLastAnrStateLocked(windowLabel, reason);
6277}
6278
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05006279void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
6280 const std::string& reason) {
6281 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006282 updateLastAnrStateLocked(windowLabel, reason);
6283}
6284
6285void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
6286 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006287 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07006288 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006289 struct tm tm;
6290 localtime_r(&t, &tm);
6291 char timestr[64];
6292 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006293 mLastAnrState.clear();
6294 mLastAnrState += INDENT "ANR:\n";
6295 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006296 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
6297 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006298 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006299}
6300
Prabir Pradhancef936d2021-07-21 16:17:52 +00006301void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
Prabir Pradhan24047542023-11-02 17:14:59 +00006302 const KeyEntry& entry) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006303 const KeyEvent event = createKeyEvent(entry);
6304 nsecs_t delay = 0;
6305 { // release lock
6306 scoped_unlock unlock(mLock);
6307 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00006308 delay = mPolicy.interceptKeyBeforeDispatching(focusedWindowToken, event, entry.policyFlags);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006309 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
6310 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
6311 std::to_string(t.duration().count()).c_str());
6312 }
6313 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08006314
6315 if (delay < 0) {
Michael Wright5caf55a2022-11-24 22:31:42 +00006316 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00006317 } else if (delay == 0) {
Michael Wright5caf55a2022-11-24 22:31:42 +00006318 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006319 } else {
Michael Wright5caf55a2022-11-24 22:31:42 +00006320 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006321 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006322 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006323}
6324
Prabir Pradhancef936d2021-07-21 16:17:52 +00006325void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006326 std::optional<gui::Pid> pid,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006327 std::string reason) {
Yabin Cui8eb9c552023-06-08 18:05:07 +00006328 auto command = [this, token, pid, r = std::move(reason)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006329 scoped_unlock unlock(mLock);
Yabin Cuiced952f2023-06-09 21:12:51 +00006330 mPolicy.notifyWindowUnresponsive(token, pid, r);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006331 };
6332 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006333}
6334
Prabir Pradhanedd96402022-02-15 01:46:16 -08006335void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006336 std::optional<gui::Pid> pid) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08006337 auto command = [this, token, pid]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006338 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006339 mPolicy.notifyWindowResponsive(token, pid);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006340 };
6341 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006342}
6343
6344/**
6345 * Tell the policy that a connection has become unresponsive so that it can start ANR.
6346 * Check whether the connection of interest is a monitor or a window, and add the corresponding
6347 * command entry to the command queue.
6348 */
6349void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
6350 std::string reason) {
6351 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006352 std::optional<gui::Pid> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006353 if (connection.monitor) {
6354 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
6355 reason.c_str());
Prabir Pradhanedd96402022-02-15 01:46:16 -08006356 pid = findMonitorPidByTokenLocked(connectionToken);
6357 } else {
6358 // The connection is a window
6359 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
6360 reason.c_str());
6361 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6362 if (handle != nullptr) {
6363 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006364 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006365 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08006366 sendWindowUnresponsiveCommandLocked(connectionToken, pid, std::move(reason));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006367}
6368
6369/**
6370 * Tell the policy that a connection has become responsive so that it can stop ANR.
6371 */
6372void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
6373 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006374 std::optional<gui::Pid> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006375 if (connection.monitor) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08006376 pid = findMonitorPidByTokenLocked(connectionToken);
6377 } else {
6378 // The connection is a window
6379 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6380 if (handle != nullptr) {
6381 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006382 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006383 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08006384 sendWindowResponsiveCommandLocked(connectionToken, pid);
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006385}
6386
Prabir Pradhan24047542023-11-02 17:14:59 +00006387std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptable(
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006388 const std::shared_ptr<Connection>& connection, DispatchEntry& dispatchEntry,
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006389 const KeyEntry& keyEntry, bool handled) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006390 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006391 if (!handled) {
6392 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006393 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006394 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006395 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006396 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006397
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006398 // Get the fallback key state.
6399 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006400 int32_t originalKeyCode = keyEntry.keyCode;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006401 std::optional<int32_t> fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006402 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006403 connection->inputState.removeFallbackKey(originalKeyCode);
6404 }
6405
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006406 if (handled || !dispatchEntry.hasForegroundTarget()) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006407 // If the application handles the original key for which we previously
6408 // generated a fallback or if the window is not a foreground window,
6409 // then cancel the associated fallback key, if any.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006410 if (fallbackKeyCode) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006411 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006412 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6413 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
6414 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6415 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
6416 keyEntry.policyFlags);
6417 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006418 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006419 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006420
6421 mLock.unlock();
6422
Prabir Pradhana41d2442023-04-20 21:30:40 +00006423 if (const auto unhandledKeyFallback =
6424 mPolicy.dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
6425 event, keyEntry.policyFlags);
6426 unhandledKeyFallback) {
6427 event = *unhandledKeyFallback;
6428 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006429
6430 mLock.lock();
6431
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006432 // Cancel the fallback key.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006433 if (*fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00006434 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006435 "application handled the original non-fallback key "
6436 "or is no longer a foreground target, "
6437 "canceling previously dispatched fallback key");
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006438 options.keyCode = *fallbackKeyCode;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006439 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006440 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006441 connection->inputState.removeFallbackKey(originalKeyCode);
6442 }
6443 } else {
6444 // If the application did not handle a non-fallback key, first check
6445 // that we are in a good state to perform unhandled key event processing
6446 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006447 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006448 if (!fallbackKeyCode && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006449 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6450 ALOGD("Unhandled key event: Skipping unhandled key event processing "
6451 "since this is not an initial down. "
6452 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6453 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6454 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006455 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006456 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006457
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006458 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006459 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6460 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
6461 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6462 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6463 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006464 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006465
6466 mLock.unlock();
6467
Prabir Pradhana41d2442023-04-20 21:30:40 +00006468 bool fallback = false;
6469 if (auto fb = mPolicy.dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
6470 event, keyEntry.policyFlags);
6471 fb) {
6472 fallback = true;
6473 event = *fb;
6474 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006475
6476 mLock.lock();
6477
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08006478 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006479 connection->inputState.removeFallbackKey(originalKeyCode);
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006480 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006481 }
6482
6483 // Latch the fallback keycode for this key on an initial down.
6484 // The fallback keycode cannot change at any other point in the lifecycle.
6485 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006486 if (fallback) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006487 *fallbackKeyCode = event.getKeyCode();
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006488 } else {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006489 *fallbackKeyCode = AKEYCODE_UNKNOWN;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006490 }
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006491 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006492 }
6493
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006494 ALOG_ASSERT(fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006495
6496 // Cancel the fallback key if the policy decides not to send it anymore.
6497 // We will continue to dispatch the key to the policy but we will no
6498 // longer dispatch a fallback key to the application.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006499 if (*fallbackKeyCode != AKEYCODE_UNKNOWN &&
6500 (!fallback || *fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006501 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6502 if (fallback) {
6503 ALOGD("Unhandled key event: Policy requested to send key %d"
6504 "as a fallback for %d, but on the DOWN it had requested "
6505 "to send %d instead. Fallback canceled.",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006506 event.getKeyCode(), originalKeyCode, *fallbackKeyCode);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006507 } else {
6508 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6509 "but on the DOWN it had requested to send %d. "
6510 "Fallback canceled.",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006511 originalKeyCode, *fallbackKeyCode);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006512 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006513 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006514
Michael Wrightfb04fd52022-11-24 22:31:11 +00006515 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006516 "canceling fallback, policy no longer desires it");
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006517 options.keyCode = *fallbackKeyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006518 synthesizeCancelationEventsForConnectionLocked(connection, options);
6519
6520 fallback = false;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006521 *fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006522 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006523 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006524 }
6525 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006526
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006527 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6528 {
6529 std::string msg;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006530 const std::map<int32_t, int32_t>& fallbackKeys =
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006531 connection->inputState.getFallbackKeys();
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006532 for (const auto& [key, value] : fallbackKeys) {
6533 msg += StringPrintf(", %d->%d", key, value);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006534 }
6535 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6536 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006537 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006538 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006539
6540 if (fallback) {
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006541 // Return the fallback key that we want dispatched to the channel.
6542 std::unique_ptr<KeyEntry> newEntry =
6543 std::make_unique<KeyEntry>(mIdGenerator.nextId(), keyEntry.injectionState,
6544 event.getEventTime(), event.getDeviceId(),
6545 event.getSource(), event.getDisplayId(),
6546 keyEntry.policyFlags, keyEntry.action,
6547 event.getFlags() | AKEY_EVENT_FLAG_FALLBACK,
6548 *fallbackKeyCode, event.getScanCode(),
6549 event.getMetaState(), event.getRepeatCount(),
6550 event.getDownTime());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006551 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6552 ALOGD("Unhandled key event: Dispatching fallback key. "
6553 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006554 originalKeyCode, *fallbackKeyCode, keyEntry.metaState);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006555 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006556 return newEntry;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006557 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006558 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6559 ALOGD("Unhandled key event: No fallback key.");
6560 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006561
6562 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006563 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006564 }
6565 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006566 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08006567}
6568
Michael Wrightd02c5b62014-02-10 15:10:22 -08006569void InputDispatcher::traceInboundQueueLengthLocked() {
6570 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006571 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006572 }
6573}
6574
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006575void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006576 if (ATRACE_ENABLED()) {
6577 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006578 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6579 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006580 }
6581}
6582
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006583void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006584 if (ATRACE_ENABLED()) {
6585 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006586 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6587 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006588 }
6589}
6590
Siarhei Vishniakou5e20f272023-06-08 17:24:44 -07006591void InputDispatcher::dump(std::string& dump) const {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006592 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006593
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006594 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006595 dumpDispatchStateLocked(dump);
6596
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006597 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006598 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006599 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006600 }
6601}
6602
6603void InputDispatcher::monitor() {
6604 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006605 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006606 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006607 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006608}
6609
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006610/**
6611 * Wake up the dispatcher and wait until it processes all events and commands.
6612 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6613 * this method can be safely called from any thread, as long as you've ensured that
6614 * the work you are interested in completing has already been queued.
6615 */
Siarhei Vishniakoua66d65e2023-06-16 10:32:51 -07006616bool InputDispatcher::waitForIdle() const {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006617 /**
6618 * Timeout should represent the longest possible time that a device might spend processing
6619 * events and commands.
6620 */
6621 constexpr std::chrono::duration TIMEOUT = 100ms;
6622 std::unique_lock lock(mLock);
6623 mLooper->wake();
6624 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6625 return result == std::cv_status::no_timeout;
6626}
6627
Vishnu Naire798b472020-07-23 13:52:21 -07006628/**
6629 * Sets focus to the window identified by the token. This must be called
6630 * after updating any input window handles.
6631 *
6632 * Params:
6633 * request.token - input channel token used to identify the window that should gain focus.
6634 * request.focusedToken - the token that the caller expects currently to be focused. If the
6635 * specified token does not match the currently focused window, this request will be dropped.
6636 * If the specified focused token matches the currently focused window, the call will succeed.
6637 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6638 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6639 * when requesting the focus change. This determines which request gets
6640 * precedence if there is a focus change request from another source such as pointer down.
6641 */
Vishnu Nair958da932020-08-21 17:12:37 -07006642void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6643 { // acquire lock
6644 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006645 std::optional<FocusResolver::FocusChanges> changes =
6646 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6647 if (changes) {
6648 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006649 }
6650 } // release lock
6651 // Wake up poll loop since it may need to make new input dispatching choices.
6652 mLooper->wake();
6653}
6654
Vishnu Nairc519ff72021-01-21 08:23:08 -08006655void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6656 if (changes.oldFocus) {
6657 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006658 if (focusedInputChannel) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00006659 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006660 "focus left window");
6661 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Harry Cutts33476232023-01-30 19:57:29 +00006662 enqueueFocusEventLocked(changes.oldFocus, /*hasFocus=*/false, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006663 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006664 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006665 if (changes.newFocus) {
Siarhei Vishniakouc033dfb2023-10-03 10:45:16 -07006666 resetNoFocusedWindowTimeoutLocked();
Harry Cutts33476232023-01-30 19:57:29 +00006667 enqueueFocusEventLocked(changes.newFocus, /*hasFocus=*/true, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006668 }
6669
Prabir Pradhan99987712020-11-10 18:43:05 -08006670 // If a window has pointer capture, then it must have focus. We need to ensure that this
6671 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6672 // If the window loses focus before it loses pointer capture, then the window can be in a state
6673 // where it has pointer capture but not focus, violating the contract. Therefore we must
6674 // dispatch the pointer capture event before the focus event. Since focus events are added to
6675 // the front of the queue (above), we add the pointer capture event to the front of the queue
6676 // after the focus events are added. This ensures the pointer capture event ends up at the
6677 // front.
6678 disablePointerCaptureForcedLocked();
6679
Vishnu Nairc519ff72021-01-21 08:23:08 -08006680 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006681 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006682 }
6683}
Vishnu Nair958da932020-08-21 17:12:37 -07006684
Prabir Pradhan99987712020-11-10 18:43:05 -08006685void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006686 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006687 return;
6688 }
6689
6690 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6691
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006692 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006693 setPointerCaptureLocked(false);
6694 }
6695
6696 if (!mWindowTokenWithPointerCapture) {
6697 // No need to send capture changes because no window has capture.
6698 return;
6699 }
6700
6701 if (mPendingEvent != nullptr) {
6702 // Move the pending event to the front of the queue. This will give the chance
6703 // for the pending event to be dropped if it is a captured event.
6704 mInboundQueue.push_front(mPendingEvent);
6705 mPendingEvent = nullptr;
6706 }
6707
6708 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006709 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006710 mInboundQueue.push_front(std::move(entry));
6711}
6712
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006713void InputDispatcher::setPointerCaptureLocked(bool enable) {
6714 mCurrentPointerCaptureRequest.enable = enable;
6715 mCurrentPointerCaptureRequest.seq++;
6716 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006717 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006718 mPolicy.setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006719 };
6720 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006721}
6722
Vishnu Nair599f1412021-06-21 10:39:58 -07006723void InputDispatcher::displayRemoved(int32_t displayId) {
6724 { // acquire lock
6725 std::scoped_lock _l(mLock);
6726 // Set an empty list to remove all handles from the specific display.
Harry Cutts101ee9b2023-07-06 18:04:14 +00006727 setInputWindowsLocked(/*windowInfoHandles=*/{}, displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006728 setFocusedApplicationLocked(displayId, nullptr);
6729 // Call focus resolver to clean up stale requests. This must be called after input windows
6730 // have been removed for the removed display.
6731 mFocusResolver.displayRemoved(displayId);
Christine Franksb768bb42021-11-29 12:11:31 -08006732 // Reset pointer capture eligibility, regardless of previous state.
6733 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
Antonio Kantek15beb512022-06-13 22:35:41 +00006734 // Remove the associated touch mode state.
6735 mTouchModePerDisplay.erase(displayId);
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07006736 mVerifiersByDisplay.erase(displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006737 } // release lock
6738
6739 // Wake up poll loop since it may need to make new input dispatching choices.
6740 mLooper->wake();
6741}
6742
Patrick Williamsd828f302023-04-28 17:52:08 -05006743void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update) {
chaviw15fab6f2021-06-07 14:15:52 -05006744 // The listener sends the windows as a flattened array. Separate the windows by display for
6745 // more convenient parsing.
6746 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
Patrick Williamsd828f302023-04-28 17:52:08 -05006747 for (const auto& info : update.windowInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006748 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07006749 handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
chaviw15fab6f2021-06-07 14:15:52 -05006750 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006751
6752 { // acquire lock
6753 std::scoped_lock _l(mLock);
Prabir Pradhan814fe082022-07-22 20:22:18 +00006754
6755 // Ensure that we have an entry created for all existing displays so that if a displayId has
6756 // no windows, we can tell that the windows were removed from the display.
6757 for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
6758 handlesPerDisplay[displayId];
6759 }
6760
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006761 mDisplayInfos.clear();
Patrick Williamsd828f302023-04-28 17:52:08 -05006762 for (const auto& displayInfo : update.displayInfos) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006763 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6764 }
6765
6766 for (const auto& [displayId, handles] : handlesPerDisplay) {
6767 setInputWindowsLocked(handles, displayId);
6768 }
Patrick Williams9464b2c2023-05-23 11:22:04 -05006769
6770 if (update.vsyncId < mWindowInfosVsyncId) {
6771 ALOGE("Received out of order window infos update. Last update vsync id: %" PRId64
6772 ", current update vsync id: %" PRId64,
6773 mWindowInfosVsyncId, update.vsyncId);
6774 }
6775 mWindowInfosVsyncId = update.vsyncId;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006776 }
6777 // Wake up poll loop since it may need to make new input dispatching choices.
6778 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006779}
6780
Vishnu Nair062a8672021-09-03 16:07:44 -07006781bool InputDispatcher::shouldDropInput(
6782 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006783 if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
6784 (windowHandle->getInfo()->inputConfig.test(
6785 WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
Vishnu Nair062a8672021-09-03 16:07:44 -07006786 isWindowObscuredLocked(windowHandle))) {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006787 ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on "
6788 "display %" PRId32 ".",
Vishnu Nair062a8672021-09-03 16:07:44 -07006789 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006790 windowHandle->getInfo()->inputConfig.string().c_str(),
Vishnu Nair062a8672021-09-03 16:07:44 -07006791 windowHandle->getInfo()->displayId);
6792 return true;
6793 }
6794 return false;
6795}
6796
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006797void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
Patrick Williamsd828f302023-04-28 17:52:08 -05006798 const gui::WindowInfosUpdate& update) {
6799 mDispatcher.onWindowInfosChanged(update);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006800}
6801
Arthur Hungdfd528e2021-12-08 13:23:04 +00006802void InputDispatcher::cancelCurrentTouch() {
6803 {
6804 std::scoped_lock _l(mLock);
6805 ALOGD("Canceling all ongoing pointer gestures on all displays.");
Michael Wrightfb04fd52022-11-24 22:31:11 +00006806 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Arthur Hungdfd528e2021-12-08 13:23:04 +00006807 "cancel current touch");
6808 synthesizeCancelationEventsForAllConnectionsLocked(options);
6809
6810 mTouchStatesByDisplay.clear();
Arthur Hungdfd528e2021-12-08 13:23:04 +00006811 }
6812 // Wake up poll loop since there might be work to do.
6813 mLooper->wake();
6814}
6815
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08006816void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout) {
6817 std::scoped_lock _l(mLock);
6818 mMonitorDispatchingTimeout = timeout;
6819}
6820
Arthur Hungc539dbb2022-12-08 07:45:36 +00006821void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
6822 const sp<WindowInfoHandle>& oldWindowHandle,
6823 const sp<WindowInfoHandle>& newWindowHandle,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006824 TouchState& state, int32_t deviceId,
6825 const PointerProperties& pointerProperties,
Siarhei Vishniakoubf880522023-05-01 11:03:22 -07006826 std::vector<InputTarget>& targets) const {
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006827 std::vector<PointerProperties> pointers{pointerProperties};
Arthur Hungc539dbb2022-12-08 07:45:36 +00006828 const bool oldHasWallpaper = oldWindowHandle->getInfo()->inputConfig.test(
6829 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6830 const bool newHasWallpaper = targetFlags.test(InputTarget::Flags::FOREGROUND) &&
6831 newWindowHandle->getInfo()->inputConfig.test(
6832 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6833 const sp<WindowInfoHandle> oldWallpaper =
6834 oldHasWallpaper ? state.getWallpaperWindow() : nullptr;
6835 const sp<WindowInfoHandle> newWallpaper =
6836 newHasWallpaper ? findWallpaperWindowBelow(newWindowHandle) : nullptr;
6837 if (oldWallpaper == newWallpaper) {
6838 return;
6839 }
6840
6841 if (oldWallpaper != nullptr) {
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08006842 const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper);
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006843 addPointerWindowTargetLocked(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006844 oldTouchedWindow.targetFlags, getPointerIds(pointers),
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006845 oldTouchedWindow.getDownTimeInTarget(deviceId), targets);
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006846 state.removeTouchingPointerFromWindow(deviceId, pointerProperties.id, oldWallpaper);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006847 }
6848
6849 if (newWallpaper != nullptr) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006850 state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::SLIPPERY_ENTER,
6851 InputTarget::Flags::WINDOW_IS_OBSCURED |
Arthur Hungc539dbb2022-12-08 07:45:36 +00006852 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006853 deviceId, pointers);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006854 }
6855}
6856
6857void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags,
6858 ftl::Flags<InputTarget::Flags> newTargetFlags,
6859 const sp<WindowInfoHandle> fromWindowHandle,
6860 const sp<WindowInfoHandle> toWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006861 TouchState& state, int32_t deviceId,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006862 const std::vector<PointerProperties>& pointers) {
Arthur Hungc539dbb2022-12-08 07:45:36 +00006863 const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
6864 fromWindowHandle->getInfo()->inputConfig.test(
6865 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6866 const bool newHasWallpaper = newTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
6867 toWindowHandle->getInfo()->inputConfig.test(
6868 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6869
6870 const sp<WindowInfoHandle> oldWallpaper =
6871 oldHasWallpaper ? state.getWallpaperWindow() : nullptr;
6872 const sp<WindowInfoHandle> newWallpaper =
6873 newHasWallpaper ? findWallpaperWindowBelow(toWindowHandle) : nullptr;
6874 if (oldWallpaper == newWallpaper) {
6875 return;
6876 }
6877
6878 if (oldWallpaper != nullptr) {
6879 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6880 "transferring touch focus to another window");
6881 state.removeWindowByToken(oldWallpaper->getToken());
6882 synthesizeCancelationEventsForWindowLocked(oldWallpaper, options);
6883 }
6884
6885 if (newWallpaper != nullptr) {
6886 nsecs_t downTimeInTarget = now();
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006887 ftl::Flags<InputTarget::Flags> wallpaperFlags = oldTargetFlags & InputTarget::Flags::SPLIT;
Arthur Hungc539dbb2022-12-08 07:45:36 +00006888 wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED |
6889 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006890 state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
Siarhei Vishniakou1ff00cc2023-12-13 16:12:13 -08006891 deviceId, pointers, downTimeInTarget);
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006892 std::shared_ptr<Connection> wallpaperConnection =
6893 getConnectionLocked(newWallpaper->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00006894 if (wallpaperConnection != nullptr) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006895 std::shared_ptr<Connection> toConnection =
6896 getConnectionLocked(toWindowHandle->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00006897 toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState);
6898 synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, wallpaperConnection,
6899 wallpaperFlags);
6900 }
6901 }
6902}
6903
6904sp<WindowInfoHandle> InputDispatcher::findWallpaperWindowBelow(
6905 const sp<WindowInfoHandle>& windowHandle) const {
6906 const std::vector<sp<WindowInfoHandle>>& windowHandles =
6907 getWindowHandlesLocked(windowHandle->getInfo()->displayId);
6908 bool foundWindow = false;
6909 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
6910 if (!foundWindow && otherHandle != windowHandle) {
6911 continue;
6912 }
6913 if (windowHandle == otherHandle) {
6914 foundWindow = true;
6915 continue;
6916 }
6917
6918 if (otherHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::IS_WALLPAPER)) {
6919 return otherHandle;
6920 }
6921 }
6922 return nullptr;
6923}
6924
Siarhei Vishniakoufa2a0492023-11-14 13:13:18 -08006925void InputDispatcher::setKeyRepeatConfiguration(std::chrono::nanoseconds timeout,
6926 std::chrono::nanoseconds delay) {
Nergi Rahardi730cf3c2023-04-13 12:41:17 +09006927 std::scoped_lock _l(mLock);
6928
Siarhei Vishniakoufa2a0492023-11-14 13:13:18 -08006929 mConfig.keyRepeatTimeout = timeout.count();
6930 mConfig.keyRepeatDelay = delay.count();
Nergi Rahardi730cf3c2023-04-13 12:41:17 +09006931}
6932
Prabir Pradhan64f21d22023-11-28 21:19:42 +00006933bool InputDispatcher::isPointerInWindow(const sp<android::IBinder>& token, int32_t displayId,
6934 DeviceId deviceId, int32_t pointerId) {
6935 std::scoped_lock _l(mLock);
6936 auto touchStateIt = mTouchStatesByDisplay.find(displayId);
6937 if (touchStateIt == mTouchStatesByDisplay.end()) {
6938 return false;
6939 }
6940 for (const TouchedWindow& window : touchStateIt->second.windows) {
6941 if (window.windowHandle->getToken() == token &&
6942 (window.hasTouchingPointer(deviceId, pointerId) ||
6943 window.hasHoveringPointer(deviceId, pointerId))) {
6944 return true;
6945 }
6946 }
6947 return false;
6948}
6949
Garfield Tane84e6f92019-08-29 17:28:41 -07006950} // namespace android::inputdispatcher