blob: 67e48a266d2cad249e2fdf19ad6cedc28e851001 [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 Vishniakou6773db62023-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 Vishniakou17f12282023-11-02 13:40:29 -070075static const bool REMOVE_APP_SWITCH_DROPS = input_flags::remove_app_switch_drops();
Michael Wrightd02c5b62014-02-10 15:10:22 -080076
Garfield Tane84e6f92019-08-29 17:28:41 -070077namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080078
Prabir Pradhancef936d2021-07-21 16:17:52 +000079namespace {
Prabir Pradhancef936d2021-07-21 16:17:52 +000080// Temporarily releases a held mutex for the lifetime of the instance.
81// Named to match std::scoped_lock
82class scoped_unlock {
83public:
84 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
85 ~scoped_unlock() { mMutex.lock(); }
86
87private:
88 std::mutex& mMutex;
89};
90
Michael Wrightd02c5b62014-02-10 15:10:22 -080091// Default input dispatching timeout if there is no focused application or paused window
92// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080093const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
94 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
95 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -080096
97// Amount of time to allow for all pending events to be processed when an app switch
98// key is on the way. This is used to preempt input dispatch and drop input events
99// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000100constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800101
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800102const std::chrono::duration STALE_EVENT_TIMEOUT = std::chrono::seconds(10) * HwTimeoutMultiplier();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800103
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104// 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 +0000105constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
106
107// Log a warning when an interception call takes longer than this to process.
108constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800109
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700110// Additional key latency in case a connection is still processing some motion events.
111// This will help with the case when a user touched a button that opens a new window,
112// and gives us the chance to dispatch the key to this new window.
113constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
114
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000116constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
117
Antonio Kantekea47acb2021-12-23 12:41:25 -0800118// Event log tags. See EventLogTags.logtags for reference.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000119constexpr int LOGTAG_INPUT_INTERACTION = 62000;
120constexpr int LOGTAG_INPUT_FOCUS = 62001;
Arthur Hungb3307ee2021-10-14 10:57:37 +0000121constexpr int LOGTAG_INPUT_CANCEL = 62003;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000122
Prabir Pradhan33e3baa2022-12-06 20:30:22 +0000123const ui::Transform kIdentityTransform;
124
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000125inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800126 return systemTime(SYSTEM_TIME_MONOTONIC);
127}
128
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700129inline const std::string binderToString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000130 if (binder == nullptr) {
131 return "<null>";
132 }
133 return StringPrintf("%p", binder.get());
134}
135
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000136static std::string uidString(const gui::Uid& uid) {
137 return uid.toString();
138}
139
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700140Result<void> checkKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800141 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700142 case AKEY_EVENT_ACTION_DOWN:
143 case AKEY_EVENT_ACTION_UP:
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700144 return {};
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700145 default:
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700146 return Error() << "Key event has invalid action code " << action;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800147 }
148}
149
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700150Result<void> validateKeyEvent(int32_t action) {
151 return checkKeyAction(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800152}
153
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700154Result<void> checkMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800155 switch (MotionEvent::getActionMasked(action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700156 case AMOTION_EVENT_ACTION_DOWN:
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700157 case AMOTION_EVENT_ACTION_UP: {
158 if (pointerCount != 1) {
159 return Error() << "invalid pointer count " << pointerCount;
160 }
161 return {};
162 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700163 case AMOTION_EVENT_ACTION_MOVE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700164 case AMOTION_EVENT_ACTION_HOVER_ENTER:
165 case AMOTION_EVENT_ACTION_HOVER_MOVE:
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700166 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
167 if (pointerCount < 1) {
168 return Error() << "invalid pointer count " << pointerCount;
169 }
170 return {};
171 }
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800172 case AMOTION_EVENT_ACTION_CANCEL:
173 case AMOTION_EVENT_ACTION_OUTSIDE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700174 case AMOTION_EVENT_ACTION_SCROLL:
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700175 return {};
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700176 case AMOTION_EVENT_ACTION_POINTER_DOWN:
177 case AMOTION_EVENT_ACTION_POINTER_UP: {
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800178 const int32_t index = MotionEvent::getActionIndex(action);
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700179 if (index < 0) {
180 return Error() << "invalid index " << index << " for "
181 << MotionEvent::actionToString(action);
182 }
183 if (index >= pointerCount) {
184 return Error() << "invalid index " << index << " for pointerCount " << pointerCount;
185 }
186 if (pointerCount <= 1) {
187 return Error() << "invalid pointer count " << pointerCount << " for "
188 << MotionEvent::actionToString(action);
189 }
190 return {};
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700191 }
192 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700193 case AMOTION_EVENT_ACTION_BUTTON_RELEASE: {
194 if (actionButton == 0) {
195 return Error() << "action button should be nonzero for "
196 << MotionEvent::actionToString(action);
197 }
198 return {};
199 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700200 default:
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700201 return Error() << "invalid action " << action;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800202 }
203}
204
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000205int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500206 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
207}
208
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700209Result<void> validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
210 const PointerProperties* pointerProperties) {
211 Result<void> actionCheck = checkMotionAction(action, actionButton, pointerCount);
212 if (!actionCheck.ok()) {
213 return actionCheck;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214 }
215 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700216 return Error() << "Motion event has invalid pointer count " << pointerCount
217 << "; value must be between 1 and " << MAX_POINTERS << ".";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800218 }
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800219 std::bitset<MAX_POINTER_ID + 1> pointerIdBits;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800220 for (size_t i = 0; i < pointerCount; i++) {
221 int32_t id = pointerProperties[i].id;
222 if (id < 0 || id > MAX_POINTER_ID) {
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700223 return Error() << "Motion event has invalid pointer id " << id
224 << "; value must be between 0 and " << MAX_POINTER_ID;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800225 }
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800226 if (pointerIdBits.test(id)) {
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700227 return Error() << "Motion event has duplicate pointer id " << id;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800228 }
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800229 pointerIdBits.set(id);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800230 }
Siarhei Vishniakou6773db62023-04-21 11:30:20 -0700231 return {};
232}
233
234Result<void> validateInputEvent(const InputEvent& event) {
235 switch (event.getType()) {
236 case InputEventType::KEY: {
237 const KeyEvent& key = static_cast<const KeyEvent&>(event);
238 const int32_t action = key.getAction();
239 return validateKeyEvent(action);
240 }
241 case InputEventType::MOTION: {
242 const MotionEvent& motion = static_cast<const MotionEvent&>(event);
243 const int32_t action = motion.getAction();
244 const size_t pointerCount = motion.getPointerCount();
245 const PointerProperties* pointerProperties = motion.getPointerProperties();
246 const int32_t actionButton = motion.getActionButton();
247 return validateMotionEvent(action, actionButton, pointerCount, pointerProperties);
248 }
249 default: {
250 return {};
251 }
252 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800253}
254
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000255std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800256 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000257 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800258 }
259
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000260 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800261 bool first = true;
262 Region::const_iterator cur = region.begin();
263 Region::const_iterator const tail = region.end();
264 while (cur != tail) {
265 if (first) {
266 first = false;
267 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800268 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800269 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800270 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800271 cur++;
272 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000273 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800274}
275
Prabir Pradhan8c90d782023-09-15 21:16:44 +0000276std::string dumpQueue(const std::deque<std::unique_ptr<DispatchEntry>>& queue,
277 nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500278 constexpr size_t maxEntries = 50; // max events to print
279 constexpr size_t skipBegin = maxEntries / 2;
280 const size_t skipEnd = queue.size() - maxEntries / 2;
281 // skip from maxEntries / 2 ... size() - maxEntries/2
282 // only print from 0 .. skipBegin and then from skipEnd .. size()
283
284 std::string dump;
285 for (size_t i = 0; i < queue.size(); i++) {
286 const DispatchEntry& entry = *queue[i];
287 if (i >= skipBegin && i < skipEnd) {
288 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
289 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
290 continue;
291 }
292 dump.append(INDENT4);
293 dump += entry.eventEntry->getDescription();
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +0000294 dump += StringPrintf(", seq=%" PRIu32 ", targetFlags=%s, age=%" PRId64 "ms", entry.seq,
295 entry.targetFlags.string().c_str(),
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500296 ns2ms(currentTime - entry.eventEntry->eventTime));
297 if (entry.deliveryTime != 0) {
298 // This entry was delivered, so add information on how long we've been waiting
299 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
300 }
301 dump.append("\n");
302 }
303 return dump;
304}
305
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700306/**
307 * Find the entry in std::unordered_map by key, and return it.
308 * If the entry is not found, return a default constructed entry.
309 *
310 * Useful when the entries are vectors, since an empty vector will be returned
311 * if the entry is not found.
312 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
313 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700314template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000315V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700316 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700317 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800318}
319
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000320bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700321 if (first == second) {
322 return true;
323 }
324
325 if (first == nullptr || second == nullptr) {
326 return false;
327 }
328
329 return first->getToken() == second->getToken();
330}
331
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000332bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000333 if (first == nullptr || second == nullptr) {
334 return false;
335 }
336 return first->applicationInfo.token != nullptr &&
337 first->applicationInfo.token == second->applicationInfo.token;
338}
339
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800340template <typename T>
341size_t firstMarkedBit(T set) {
342 // TODO: replace with std::countr_zero from <bit> when that's available
343 LOG_ALWAYS_FATAL_IF(set.none());
344 size_t i = 0;
345 while (!set.test(i)) {
346 i++;
347 }
348 return i;
349}
350
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800351std::unique_ptr<DispatchEntry> createDispatchEntry(
Prabir Pradhan24047542023-11-02 17:14:59 +0000352 const InputTarget& inputTarget, std::shared_ptr<const EventEntry> eventEntry,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800353 ftl::Flags<InputTarget::Flags> inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700354 if (inputTarget.useDefaultPointerTransform()) {
355 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700356 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700357 inputTarget.displayTransform,
358 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000359 }
360
361 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
362 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
363
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700364 std::vector<PointerCoords> pointerCoords;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700365 pointerCoords.resize(motionEntry.getPointerCount());
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000366
367 // Use the first pointer information to normalize all other pointers. This could be any pointer
368 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700369 // uses the transform for the normalized pointer.
370 const ui::Transform& firstPointerTransform =
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800371 inputTarget.pointerTransforms[firstMarkedBit(inputTarget.pointerIds)];
chaviw1ff3d1e2020-07-01 15:53:47 -0700372 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000373
374 // Iterate through all pointers in the event to normalize against the first.
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700375 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount(); pointerIndex++) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000376 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
377 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700378 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000379
380 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700381 // First, apply the current pointer's transform to update the coordinates into
382 // window space.
383 pointerCoords[pointerIndex].transform(currTransform);
384 // Next, apply the inverse transform of the normalized coordinates so the
385 // current coordinates are transformed into the normalized coordinate space.
386 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000387 }
388
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700389 std::unique_ptr<MotionEntry> combinedMotionEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +0000390 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.injectionState,
391 motionEntry.eventTime, motionEntry.deviceId,
392 motionEntry.source, motionEntry.displayId,
393 motionEntry.policyFlags, motionEntry.action,
394 motionEntry.actionButton, motionEntry.flags,
395 motionEntry.metaState, motionEntry.buttonState,
396 motionEntry.classification, motionEntry.edgeFlags,
397 motionEntry.xPrecision, motionEntry.yPrecision,
398 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
399 motionEntry.downTime, motionEntry.pointerProperties,
400 pointerCoords);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000401
402 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700403 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700404 firstPointerTransform, inputTarget.displayTransform,
405 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000406 return dispatchEntry;
407}
408
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000409status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
410 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700411 std::unique_ptr<InputChannel> uniqueServerChannel;
412 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
413
414 serverChannel = std::move(uniqueServerChannel);
415 return result;
416}
417
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500418template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000419bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500420 if (lhs == nullptr && rhs == nullptr) {
421 return true;
422 }
423 if (lhs == nullptr || rhs == nullptr) {
424 return false;
425 }
426 return *lhs == *rhs;
427}
428
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000429KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000430 KeyEvent event;
431 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
432 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
433 entry.repeatCount, entry.downTime, entry.eventTime);
434 return event;
435}
436
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000437bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000438 // Do not keep track of gesture monitors. They receive every event and would disproportionately
439 // affect the statistics.
440 if (connection.monitor) {
441 return false;
442 }
443 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
444 if (!connection.responsive) {
445 return false;
446 }
447 return true;
448}
449
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000450bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000451 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
452 const int32_t& inputEventId = eventEntry.id;
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000453 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
454 return false;
455 }
456 // Only track latency for events that originated from hardware
457 if (eventEntry.isSynthesized()) {
458 return false;
459 }
460 const EventEntry::Type& inputEventEntryType = eventEntry.type;
461 if (inputEventEntryType == EventEntry::Type::KEY) {
462 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
463 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
464 return false;
465 }
466 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
467 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
468 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
469 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
470 return false;
471 }
472 } else {
473 // Not a key or a motion
474 return false;
475 }
476 if (!shouldReportMetricsForConnection(connection)) {
477 return false;
478 }
479 return true;
480}
481
Prabir Pradhancef936d2021-07-21 16:17:52 +0000482/**
483 * Connection is responsive if it has no events in the waitQueue that are older than the
484 * current time.
485 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000486bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000487 const nsecs_t currentTime = now();
Prabir Pradhan8c90d782023-09-15 21:16:44 +0000488 for (const auto& dispatchEntry : connection.waitQueue) {
489 if (dispatchEntry->timeoutTime < currentTime) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000490 return false;
491 }
492 }
493 return true;
494}
495
Antonio Kantekf16f2832021-09-28 04:39:20 +0000496// Returns true if the event type passed as argument represents a user activity.
497bool isUserActivityEvent(const EventEntry& eventEntry) {
498 switch (eventEntry.type) {
Josep del Riob3981622023-04-18 15:49:45 +0000499 case EventEntry::Type::CONFIGURATION_CHANGED:
500 case EventEntry::Type::DEVICE_RESET:
501 case EventEntry::Type::DRAG:
Antonio Kantekf16f2832021-09-28 04:39:20 +0000502 case EventEntry::Type::FOCUS:
503 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Antonio Kantekf16f2832021-09-28 04:39:20 +0000504 case EventEntry::Type::SENSOR:
Josep del Riob3981622023-04-18 15:49:45 +0000505 case EventEntry::Type::TOUCH_MODE_CHANGED:
Antonio Kantekf16f2832021-09-28 04:39:20 +0000506 return false;
Antonio Kantekf16f2832021-09-28 04:39:20 +0000507 case EventEntry::Type::KEY:
508 case EventEntry::Type::MOTION:
509 return true;
510 }
511}
512
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800513// Returns true if the given window can accept pointer events at the given display location.
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000514bool windowAcceptsTouchAt(const WindowInfo& windowInfo, int32_t displayId, float x, float y,
Prabir Pradhan33e3baa2022-12-06 20:30:22 +0000515 bool isStylus, const ui::Transform& displayTransform) {
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800516 const auto inputConfig = windowInfo.inputConfig;
517 if (windowInfo.displayId != displayId ||
518 inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800519 return false;
520 }
Prabir Pradhand65552b2021-10-07 11:23:50 -0700521 const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800522 if (inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800523 return false;
524 }
Prabir Pradhan33e3baa2022-12-06 20:30:22 +0000525
526 // Window Manager works in the logical display coordinate space. When it specifies bounds for a
527 // window as (l, t, r, b), the range of x in [l, r) and y in [t, b) are considered to be inside
528 // the window. Points on the right and bottom edges should not be inside the window, so we need
529 // to be careful about performing a hit test when the display is rotated, since the "right" and
530 // "bottom" of the window will be different in the display (un-rotated) space compared to in the
531 // logical display in which WM determined the bounds. Perform the hit test in the logical
532 // display space to ensure these edges are considered correctly in all orientations.
533 const auto touchableRegion = displayTransform.transform(windowInfo.touchableRegion);
534 const auto p = displayTransform.transform(x, y);
535 if (!touchableRegion.contains(std::floor(p.x), std::floor(p.y))) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800536 return false;
537 }
538 return true;
539}
540
Prabir Pradhand65552b2021-10-07 11:23:50 -0700541bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
542 return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
Prabir Pradhane5626962022-10-27 20:30:53 +0000543 isStylusToolType(entry.pointerProperties[pointerIndex].toolType);
Prabir Pradhand65552b2021-10-07 11:23:50 -0700544}
545
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800546// Determines if the given window can be targeted as InputTarget::Flags::FOREGROUND.
Prabir Pradhan6dfbf262022-03-14 15:24:30 +0000547// Foreground events are only sent to "foreground targetable" windows, but not all gestures sent to
548// such window are necessarily targeted with the flag. For example, an event with ACTION_OUTSIDE can
549// be sent to such a window, but it is not a foreground event and doesn't use
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800550// InputTarget::Flags::FOREGROUND.
Prabir Pradhan6dfbf262022-03-14 15:24:30 +0000551bool canReceiveForegroundTouches(const WindowInfo& info) {
552 // A non-touchable window can still receive touch events (e.g. in the case of
553 // STYLUS_INTERCEPTOR), so prevent such windows from receiving foreground events for touches.
554 return !info.inputConfig.test(gui::WindowInfo::InputConfig::NOT_TOUCHABLE) && !info.isSpy();
555}
556
Prabir Pradhane59c6dc2023-06-13 19:53:03 +0000557bool isWindowOwnedBy(const sp<WindowInfoHandle>& windowHandle, gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -0700558 if (windowHandle == nullptr) {
559 return false;
560 }
561 const WindowInfo* windowInfo = windowHandle->getInfo();
562 if (pid == windowInfo->ownerPid && uid == windowInfo->ownerUid) {
563 return true;
564 }
565 return false;
566}
567
Prabir Pradhan5735a322022-04-11 17:23:34 +0000568// Checks targeted injection using the window's owner's uid.
569// Returns an empty string if an entry can be sent to the given window, or an error message if the
570// entry is a targeted injection whose uid target doesn't match the window owner.
571std::optional<std::string> verifyTargetedInjection(const sp<WindowInfoHandle>& window,
572 const EventEntry& entry) {
573 if (entry.injectionState == nullptr || !entry.injectionState->targetUid) {
574 // The event was not injected, or the injected event does not target a window.
575 return {};
576 }
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000577 const auto uid = *entry.injectionState->targetUid;
Prabir Pradhan5735a322022-04-11 17:23:34 +0000578 if (window == nullptr) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000579 return StringPrintf("No valid window target for injection into uid %s.",
580 uid.toString().c_str());
Prabir Pradhan5735a322022-04-11 17:23:34 +0000581 }
582 if (entry.injectionState->targetUid != window->getInfo()->ownerUid) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000583 return StringPrintf("Injected event targeted at uid %s would be dispatched to window '%s' "
584 "owned by uid %s.",
585 uid.toString().c_str(), window->getName().c_str(),
586 window->getInfo()->ownerUid.toString().c_str());
Prabir Pradhan5735a322022-04-11 17:23:34 +0000587 }
588 return {};
589}
590
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000591std::pair<float, float> resolveTouchedPosition(const MotionEntry& entry) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700592 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
593 // Always dispatch mouse events to cursor position.
594 if (isFromMouse) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000595 return {entry.xCursorPosition, entry.yCursorPosition};
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700596 }
597
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -0700598 const int32_t pointerIndex = MotionEvent::getActionIndex(entry.action);
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000599 return {entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X),
600 entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y)};
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700601}
602
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -0700603std::optional<nsecs_t> getDownTime(const EventEntry& eventEntry) {
604 if (eventEntry.type == EventEntry::Type::KEY) {
605 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
606 return keyEntry.downTime;
607 } else if (eventEntry.type == EventEntry::Type::MOTION) {
608 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
609 return motionEntry.downTime;
610 }
611 return std::nullopt;
612}
613
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000614/**
615 * Compare the old touch state to the new touch state, and generate the corresponding touched
616 * windows (== input targets).
617 * If a window had the hovering pointer, but now it doesn't, produce HOVER_EXIT for that window.
618 * If the pointer just entered the new window, produce HOVER_ENTER.
619 * For pointers remaining in the window, produce HOVER_MOVE.
620 */
621std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState,
622 const TouchState& newTouchState,
623 const MotionEntry& entry) {
624 std::vector<TouchedWindow> out;
625 const int32_t maskedAction = MotionEvent::getActionMasked(entry.action);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -0700626
627 if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
628 // ACTION_SCROLL events should not affect the hovering pointer dispatch
629 return {};
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000630 }
631
632 // We should consider all hovering pointers here. But for now, just use the first one
633 const int32_t pointerId = entry.pointerProperties[0].id;
634
635 std::set<sp<WindowInfoHandle>> oldWindows;
636 if (oldState != nullptr) {
637 oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId);
638 }
639
640 std::set<sp<WindowInfoHandle>> newWindows =
641 newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointerId);
642
643 // If the pointer is no longer in the new window set, send HOVER_EXIT.
644 for (const sp<WindowInfoHandle>& oldWindow : oldWindows) {
645 if (newWindows.find(oldWindow) == newWindows.end()) {
646 TouchedWindow touchedWindow;
647 touchedWindow.windowHandle = oldWindow;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000648 touchedWindow.dispatchMode = InputTarget::DispatchMode::HOVER_EXIT;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000649 out.push_back(touchedWindow);
650 }
651 }
652
653 for (const sp<WindowInfoHandle>& newWindow : newWindows) {
654 TouchedWindow touchedWindow;
655 touchedWindow.windowHandle = newWindow;
656 if (oldWindows.find(newWindow) == oldWindows.end()) {
657 // Any windows that have this pointer now, and didn't have it before, should get
658 // HOVER_ENTER
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000659 touchedWindow.dispatchMode = InputTarget::DispatchMode::HOVER_ENTER;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000660 } else {
661 // This pointer was already sent to the window. Use ACTION_HOVER_MOVE.
Siarhei Vishniakouc2eb8502023-04-11 18:33:36 -0700662 if (CC_UNLIKELY(maskedAction != AMOTION_EVENT_ACTION_HOVER_MOVE)) {
Daniel Norman2f99cdb2023-08-02 16:39:45 -0700663 android::base::LogSeverity severity = android::base::LogSeverity::FATAL;
Ameer Armalycff4fa52023-10-04 23:45:11 +0000664 if (!input_flags::a11y_crash_on_inconsistent_event_stream() &&
665 entry.flags & AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT) {
Daniel Norman2f99cdb2023-08-02 16:39:45 -0700666 // The Accessibility injected touch exploration event stream
667 // has known inconsistencies, so log ERROR instead of
668 // crashing the device with FATAL.
Daniel Norman2f99cdb2023-08-02 16:39:45 -0700669 severity = android::base::LogSeverity::ERROR;
670 }
671 LOG(severity) << "Expected ACTION_HOVER_MOVE instead of " << entry.getDescription();
Siarhei Vishniakouc2eb8502023-04-11 18:33:36 -0700672 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000673 touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000674 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700675 touchedWindow.addHoveringPointer(entry.deviceId, pointerId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000676 if (canReceiveForegroundTouches(*newWindow->getInfo())) {
677 touchedWindow.targetFlags |= InputTarget::Flags::FOREGROUND;
678 }
679 out.push_back(touchedWindow);
680 }
681 return out;
682}
683
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -0800684template <typename T>
685std::vector<T>& operator+=(std::vector<T>& left, const std::vector<T>& right) {
686 left.insert(left.end(), right.begin(), right.end());
687 return left;
688}
689
Harry Cuttsb166c002023-05-09 13:06:05 +0000690// Filter windows in a TouchState and targets in a vector to remove untrusted windows/targets from
691// both.
692void filterUntrustedTargets(TouchState& touchState, std::vector<InputTarget>& targets) {
693 std::erase_if(touchState.windows, [&](const TouchedWindow& window) {
694 if (!window.windowHandle->getInfo()->inputConfig.test(
695 WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
696 // In addition to TouchState, erase this window from the input targets! We don't have a
697 // good way to do this today except by adding a nested loop.
698 // TODO(b/282025641): simplify this code once InputTargets are being identified
699 // separately from TouchedWindows.
700 std::erase_if(targets, [&](const InputTarget& target) {
701 return target.inputChannel->getConnectionToken() == window.windowHandle->getToken();
702 });
703 return true;
704 }
705 return false;
706 });
707}
708
Siarhei Vishniakouce1fd472023-09-18 18:38:07 -0700709/**
710 * In general, touch should be always split between windows. Some exceptions:
711 * 1. Don't split touch if all of the below is true:
712 * (a) we have an active pointer down *and*
713 * (b) a new pointer is going down that's from the same device *and*
714 * (c) the window that's receiving the current pointer does not support split touch.
715 * 2. Don't split mouse events
716 */
717bool shouldSplitTouch(const TouchState& touchState, const MotionEntry& entry) {
718 if (isFromSource(entry.source, AINPUT_SOURCE_MOUSE)) {
719 // We should never split mouse events
720 return false;
721 }
722 for (const TouchedWindow& touchedWindow : touchState.windows) {
723 if (touchedWindow.windowHandle->getInfo()->isSpy()) {
724 // Spy windows should not affect whether or not touch is split.
725 continue;
726 }
727 if (touchedWindow.windowHandle->getInfo()->supportsSplitTouch()) {
728 continue;
729 }
730 if (touchedWindow.windowHandle->getInfo()->inputConfig.test(
731 gui::WindowInfo::InputConfig::IS_WALLPAPER)) {
732 // Wallpaper window should not affect whether or not touch is split
733 continue;
734 }
735
736 if (touchedWindow.hasTouchingPointers(entry.deviceId)) {
737 return false;
738 }
739 }
740 return true;
741}
742
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000743} // namespace
744
Michael Wrightd02c5b62014-02-10 15:10:22 -0800745// --- InputDispatcher ---
746
Prabir Pradhana41d2442023-04-20 21:30:40 +0000747InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy)
Garfield Tan00f511d2019-06-12 16:55:40 -0700748 : mPolicy(policy),
749 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700750 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800751 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700752 mAppSwitchSawKeyDown(false),
Colin Cross5b799302022-10-18 21:52:41 -0700753 mAppSwitchDueTime(LLONG_MAX),
Garfield Tan00f511d2019-06-12 16:55:40 -0700754 mNextUnblockedEvent(nullptr),
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800755 mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
Garfield Tan00f511d2019-06-12 16:55:40 -0700756 mDispatchEnabled(false),
757 mDispatchFrozen(false),
758 mInputFilterEnabled(false),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100759 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000760 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800761 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000762 mLatencyAggregator(),
Antonio Kantek15beb512022-06-13 22:35:41 +0000763 mLatencyTracker(&mLatencyAggregator) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700764 mLooper = sp<Looper>::make(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800765 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800766
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700767 mWindowInfoListener = sp<DispatcherWindowListener>::make(*this);
Siarhei Vishniakou31977182022-09-30 08:51:23 -0700768#if defined(__ANDROID__)
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700769 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
Siarhei Vishniakou31977182022-09-30 08:51:23 -0700770#endif
Yi Kong9b14ac62018-07-17 13:48:38 -0700771 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800772}
773
774InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000775 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800776
Prabir Pradhancef936d2021-07-21 16:17:52 +0000777 resetKeyRepeatLocked();
778 releasePendingEventLocked();
779 drainInboundQueueLocked();
780 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800781
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000782 while (!mConnectionsByToken.empty()) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -0700783 std::shared_ptr<Connection> connection = mConnectionsByToken.begin()->second;
Harry Cutts33476232023-01-30 19:57:29 +0000784 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), /*notify=*/false);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800785 }
786}
787
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700788status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700789 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700790 return ALREADY_EXISTS;
791 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700792 mThread = std::make_unique<InputThread>(
793 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
794 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700795}
796
797status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700798 if (mThread && mThread->isCallingThread()) {
799 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700800 return INVALID_OPERATION;
801 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700802 mThread.reset();
803 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700804}
805
Michael Wrightd02c5b62014-02-10 15:10:22 -0800806void InputDispatcher::dispatchOnce() {
Colin Cross5b799302022-10-18 21:52:41 -0700807 nsecs_t nextWakeupTime = LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800808 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800809 std::scoped_lock _l(mLock);
810 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800811
812 // Run a dispatch loop if there are no pending commands.
813 // The dispatch loop might enqueue commands to run afterwards.
814 if (!haveCommandsLocked()) {
815 dispatchOnceInnerLocked(&nextWakeupTime);
816 }
817
818 // Run all pending commands if there are any.
819 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000820 if (runCommandsLockedInterruptable()) {
Colin Cross5b799302022-10-18 21:52:41 -0700821 nextWakeupTime = LLONG_MIN;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800822 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800823
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700824 // If we are still waiting for ack on some events,
825 // we might have to wake up earlier to check if an app is anr'ing.
826 const nsecs_t nextAnrCheck = processAnrsLocked();
827 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
828
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800829 // We are about to enter an infinitely long sleep, because we have no commands or
830 // pending or queued events
Colin Cross5b799302022-10-18 21:52:41 -0700831 if (nextWakeupTime == LLONG_MAX) {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800832 mDispatcherEnteredIdle.notify_all();
833 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800834 } // release lock
835
836 // Wait for callback or timeout or wake. (make sure we round up, not down)
837 nsecs_t currentTime = now();
838 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
839 mLooper->pollOnce(timeoutMillis);
840}
841
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700842/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500843 * Raise ANR if there is no focused window.
844 * Before the ANR is raised, do a final state check:
845 * 1. The currently focused application must be the same one we are waiting for.
846 * 2. Ensure we still don't have a focused window.
847 */
848void InputDispatcher::processNoFocusedWindowAnrLocked() {
849 // Check if the application that we are waiting for is still focused.
850 std::shared_ptr<InputApplicationHandle> focusedApplication =
851 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
852 if (focusedApplication == nullptr ||
853 focusedApplication->getApplicationToken() !=
854 mAwaitedFocusedApplication->getApplicationToken()) {
855 // Unexpected because we should have reset the ANR timer when focused application changed
856 ALOGE("Waited for a focused window, but focused application has already changed to %s",
857 focusedApplication->getName().c_str());
858 return; // The focused application has changed.
859 }
860
chaviw98318de2021-05-19 16:45:23 -0500861 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500862 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
863 if (focusedWindowHandle != nullptr) {
864 return; // We now have a focused window. No need for ANR.
865 }
866 onAnrLocked(mAwaitedFocusedApplication);
867}
868
869/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700870 * Check if any of the connections' wait queues have events that are too old.
871 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
872 * Return the time at which we should wake up next.
873 */
874nsecs_t InputDispatcher::processAnrsLocked() {
875 const nsecs_t currentTime = now();
Colin Cross5b799302022-10-18 21:52:41 -0700876 nsecs_t nextAnrCheck = LLONG_MAX;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700877 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
878 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
879 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500880 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700881 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500882 mNoFocusedWindowTimeoutTime = std::nullopt;
Colin Cross5b799302022-10-18 21:52:41 -0700883 return LLONG_MIN;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700884 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500885 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700886 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
887 }
888 }
889
890 // Check if any connection ANRs are due
891 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
892 if (currentTime < nextAnrCheck) { // most likely scenario
893 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
894 }
895
896 // If we reached here, we have an unresponsive connection.
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -0700897 std::shared_ptr<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700898 if (connection == nullptr) {
899 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
900 return nextAnrCheck;
901 }
902 connection->responsive = false;
903 // Stop waking up for this unresponsive connection
904 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000905 onAnrLocked(connection);
Colin Cross5b799302022-10-18 21:52:41 -0700906 return LLONG_MIN;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700907}
908
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800909std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -0700910 const std::shared_ptr<Connection>& connection) {
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800911 if (connection->monitor) {
912 return mMonitorDispatchingTimeout;
913 }
914 const sp<WindowInfoHandle> window =
915 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700916 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500917 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700918 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500919 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700920}
921
Michael Wrightd02c5b62014-02-10 15:10:22 -0800922void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
923 nsecs_t currentTime = now();
924
Jeff Browndc5992e2014-04-11 01:27:26 -0700925 // Reset the key repeat timer whenever normal dispatch is suspended while the
926 // device is in a non-interactive state. This is to ensure that we abort a key
927 // repeat if the device is just coming out of sleep.
928 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800929 resetKeyRepeatLocked();
930 }
931
932 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
933 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100934 if (DEBUG_FOCUS) {
935 ALOGD("Dispatch frozen. Waiting some more.");
936 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800937 return;
938 }
939
940 // Optimize latency of app switches.
941 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
942 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
Siarhei Vishniakou6520a582023-10-27 21:53:45 -0700943 bool isAppSwitchDue;
Siarhei Vishniakou17f12282023-11-02 13:40:29 -0700944 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -0700945 isAppSwitchDue = mAppSwitchDueTime <= currentTime;
946 if (mAppSwitchDueTime < *nextWakeupTime) {
947 *nextWakeupTime = mAppSwitchDueTime;
948 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800949 }
950
951 // Ready to start a new event.
952 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700953 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700954 if (mInboundQueue.empty()) {
Siarhei Vishniakou17f12282023-11-02 13:40:29 -0700955 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -0700956 if (isAppSwitchDue) {
957 // The inbound queue is empty so the app switch key we were waiting
958 // for will never arrive. Stop waiting for it.
959 resetPendingAppSwitchLocked(false);
960 isAppSwitchDue = false;
961 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800962 }
963
964 // Synthesize a key repeat if appropriate.
965 if (mKeyRepeatState.lastKeyEntry) {
966 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
967 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
968 } else {
969 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
970 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
971 }
972 }
973 }
974
975 // Nothing to do if there is no pending event.
976 if (!mPendingEvent) {
977 return;
978 }
979 } else {
980 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700981 mPendingEvent = mInboundQueue.front();
982 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800983 traceInboundQueueLengthLocked();
984 }
985
986 // Poke user activity for this event.
987 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700988 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800989 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800990 }
991
992 // Now we have an event to dispatch.
993 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700994 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800995 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700996 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800997 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700998 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800999 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001000 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001001 }
1002
1003 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001004 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001005 }
1006
1007 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001008 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001009 const ConfigurationChangedEntry& typedEntry =
1010 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001011 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001012 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001013 break;
1014 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001015
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001016 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001017 const DeviceResetEntry& typedEntry =
1018 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001019 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001020 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001021 break;
1022 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001023
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001024 case EventEntry::Type::FOCUS: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001025 std::shared_ptr<const FocusEntry> typedEntry =
1026 std::static_pointer_cast<const FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001027 dispatchFocusLocked(currentTime, typedEntry);
1028 done = true;
1029 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
1030 break;
1031 }
1032
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001033 case EventEntry::Type::TOUCH_MODE_CHANGED: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001034 const auto typedEntry = std::static_pointer_cast<const TouchModeEntry>(mPendingEvent);
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001035 dispatchTouchModeChangeLocked(currentTime, typedEntry);
1036 done = true;
1037 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
1038 break;
1039 }
1040
Prabir Pradhan99987712020-11-10 18:43:05 -08001041 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1042 const auto typedEntry =
Prabir Pradhan24047542023-11-02 17:14:59 +00001043 std::static_pointer_cast<const PointerCaptureChangedEntry>(mPendingEvent);
Prabir Pradhan99987712020-11-10 18:43:05 -08001044 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
1045 done = true;
1046 break;
1047 }
1048
arthurhungb89ccb02020-12-30 16:19:01 +08001049 case EventEntry::Type::DRAG: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001050 std::shared_ptr<const DragEntry> typedEntry =
1051 std::static_pointer_cast<const DragEntry>(mPendingEvent);
arthurhungb89ccb02020-12-30 16:19:01 +08001052 dispatchDragLocked(currentTime, typedEntry);
1053 done = true;
1054 break;
1055 }
1056
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001057 case EventEntry::Type::KEY: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001058 std::shared_ptr<const KeyEntry> keyEntry =
1059 std::static_pointer_cast<const KeyEntry>(mPendingEvent);
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001060 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001061 if (isAppSwitchDue) {
1062 if (isAppSwitchKeyEvent(*keyEntry)) {
1063 resetPendingAppSwitchLocked(true);
1064 isAppSwitchDue = false;
1065 } else if (dropReason == DropReason::NOT_DROPPED) {
1066 dropReason = DropReason::APP_SWITCH;
1067 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001068 }
1069 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001070 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001071 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001072 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001073 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
1074 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001075 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001076 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001077 break;
1078 }
1079
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001080 case EventEntry::Type::MOTION: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001081 std::shared_ptr<const MotionEntry> motionEntry =
1082 std::static_pointer_cast<const MotionEntry>(mPendingEvent);
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001083 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001084 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
1085 dropReason = DropReason::APP_SWITCH;
1086 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001087 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001088 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou6b71b632023-10-27 21:34:46 -07001089 // The event is stale. However, only drop stale events if there isn't an ongoing
1090 // gesture. That would allow us to complete the processing of the current stroke.
1091 const auto touchStateIt = mTouchStatesByDisplay.find(motionEntry->displayId);
1092 if (touchStateIt != mTouchStatesByDisplay.end()) {
1093 const TouchState& touchState = touchStateIt->second;
1094 if (!touchState.hasTouchingPointers(motionEntry->deviceId) &&
1095 !touchState.hasHoveringPointers(motionEntry->deviceId)) {
1096 dropReason = DropReason::STALE;
1097 }
1098 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001099 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001100 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
Siarhei Vishniakoub32ea722023-12-27 23:31:32 +00001101 if (!isFromSource(motionEntry->source, AINPUT_SOURCE_CLASS_POINTER)) {
1102 // Only drop events that are focus-dispatched.
1103 dropReason = DropReason::BLOCKED;
1104 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001105 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001106 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001107 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001108 }
Chris Yef59a2f42020-10-16 12:55:26 -07001109
1110 case EventEntry::Type::SENSOR: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001111 std::shared_ptr<const SensorEntry> sensorEntry =
1112 std::static_pointer_cast<const SensorEntry>(mPendingEvent);
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001113 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001114 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
1115 dropReason = DropReason::APP_SWITCH;
1116 }
Chris Yef59a2f42020-10-16 12:55:26 -07001117 }
1118 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
1119 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
1120 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
1121 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
1122 dropReason = DropReason::STALE;
1123 }
1124 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
1125 done = true;
1126 break;
1127 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001128 }
1129
1130 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001131 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001132 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001133 }
Michael Wright3a981722015-06-10 15:26:13 +01001134 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001135
1136 releasePendingEventLocked();
Colin Cross5b799302022-10-18 21:52:41 -07001137 *nextWakeupTime = LLONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -08001138 }
1139}
1140
Siarhei Vishniakou289e9242022-02-15 14:50:16 -08001141bool InputDispatcher::isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
Siarhei Vishniakoua7333112023-10-27 13:33:29 -07001142 return mPolicy.isStaleEvent(currentTime, entry.eventTime);
Siarhei Vishniakou289e9242022-02-15 14:50:16 -08001143}
1144
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001145/**
1146 * Return true if the events preceding this incoming motion event should be dropped
1147 * Return false otherwise (the default behaviour)
1148 */
1149bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001150 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001151 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001152
1153 // Optimize case where the current application is unresponsive and the user
1154 // decides to touch a window in a different application.
1155 // If the application takes too long to catch up then we drop all events preceding
1156 // the touch into the other window.
1157 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07001158 const int32_t displayId = motionEntry.displayId;
1159 const auto [x, y] = resolveTouchedPosition(motionEntry);
Harry Cutts33476232023-01-30 19:57:29 +00001160 const bool isStylus = isPointerFromStylus(motionEntry, /*pointerIndex=*/0);
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07001161
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001162 sp<WindowInfoHandle> touchedWindowHandle =
1163 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001164 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001165 touchedWindowHandle->getApplicationToken() !=
1166 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001167 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001168 ALOGI("Pruning input queue because user touched a different application while waiting "
1169 "for %s",
1170 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001171 return true;
1172 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001173
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001174 // Alternatively, maybe there's a spy window that could handle this event.
1175 const std::vector<sp<WindowInfoHandle>> touchedSpies =
1176 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
1177 for (const auto& windowHandle : touchedSpies) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07001178 const std::shared_ptr<Connection> connection =
1179 getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +00001180 if (connection != nullptr && connection->responsive) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001181 // This spy window could take more input. Drop all events preceding this
1182 // event, so that the spy window can get a chance to receive the stream.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001183 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001184 "responsive spy window that may handle the event.",
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001185 mAwaitedFocusedApplication->getName().c_str());
1186 return true;
1187 }
1188 }
1189 }
1190
1191 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
1192 // yet been processed by some connections, the dispatcher will wait for these motion
1193 // events to be processed before dispatching the key event. This is because these motion events
1194 // may cause a new window to be launched, which the user might expect to receive focus.
1195 // To prevent waiting forever for such events, just send the key to the currently focused window
1196 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
1197 ALOGD("Received a new pointer down event, stop waiting for events to process and "
1198 "just send the pending key event to the focused window.");
1199 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001200 }
1201 return false;
1202}
1203
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001204bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001205 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001206 mInboundQueue.push_back(std::move(newEntry));
Prabir Pradhan24047542023-11-02 17:14:59 +00001207 const EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001208 traceInboundQueueLengthLocked();
1209
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001210 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001211 case EventEntry::Type::KEY: {
Prabir Pradhan5735a322022-04-11 17:23:34 +00001212 LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1213 "Unexpected untrusted event.");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001214 // Optimize app switch latency.
1215 // If the application takes too long to catch up then we drop all events preceding
1216 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001217 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001218
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001219 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001220 if (isAppSwitchKeyEvent(keyEntry)) {
1221 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
1222 mAppSwitchSawKeyDown = true;
1223 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
1224 if (mAppSwitchSawKeyDown) {
1225 if (DEBUG_APP_SWITCH) {
1226 ALOGD("App switch is pending!");
1227 }
1228 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
1229 mAppSwitchSawKeyDown = false;
1230 needWake = true;
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001231 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001232 }
1233 }
1234 }
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001235 // If a new up event comes in, and the pending event with same key code has been asked
1236 // to try again later because of the policy. We have to reset the intercept key wake up
1237 // time for it may have been handled in the policy and could be dropped.
1238 if (keyEntry.action == AKEY_EVENT_ACTION_UP && mPendingEvent &&
1239 mPendingEvent->type == EventEntry::Type::KEY) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001240 const KeyEntry& pendingKey = static_cast<const KeyEntry&>(*mPendingEvent);
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001241 if (pendingKey.keyCode == keyEntry.keyCode &&
1242 pendingKey.interceptKeyResult ==
Michael Wright5caf55a2022-11-24 22:31:42 +00001243 KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
1244 pendingKey.interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001245 pendingKey.interceptKeyWakeupTime = 0;
1246 needWake = true;
1247 }
1248 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001249 break;
1250 }
1251
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001252 case EventEntry::Type::MOTION: {
Prabir Pradhan5735a322022-04-11 17:23:34 +00001253 LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1254 "Unexpected untrusted event.");
Prabir Pradhan24047542023-11-02 17:14:59 +00001255 if (shouldPruneInboundQueueLocked(static_cast<const MotionEntry&>(entry))) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001256 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001257 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001258 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001259 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001260 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001261 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001262 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1263 break;
1264 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001265 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001266 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001267 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001268 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001269 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1270 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001271 // nothing to do
1272 break;
1273 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001274 }
1275
1276 return needWake;
1277}
1278
Prabir Pradhan24047542023-11-02 17:14:59 +00001279void InputDispatcher::addRecentEventLocked(std::shared_ptr<const EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001280 // Do not store sensor event in recent queue to avoid flooding the queue.
1281 if (entry->type != EventEntry::Type::SENSOR) {
1282 mRecentQueue.push_back(entry);
1283 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001284 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001285 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001286 }
1287}
1288
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001289sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, float x, float y,
1290 bool isStylus,
1291 bool ignoreDragWindow) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001292 // Traverse windows from front to back to find touched window.
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001293 const auto& windowHandles = getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05001294 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001295 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001296 continue;
1297 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001298
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001299 const WindowInfo& info = *windowHandle->getInfo();
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00001300 if (!info.isSpy() &&
1301 windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001302 return windowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001303 }
1304 }
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001305 return nullptr;
1306}
1307
1308std::vector<InputTarget> InputDispatcher::findOutsideTargetsLocked(
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07001309 int32_t displayId, const sp<WindowInfoHandle>& touchedWindow, int32_t pointerId) const {
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001310 if (touchedWindow == nullptr) {
1311 return {};
1312 }
1313 // Traverse windows from front to back until we encounter the touched window.
1314 std::vector<InputTarget> outsideTargets;
1315 const auto& windowHandles = getWindowHandlesLocked(displayId);
1316 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1317 if (windowHandle == touchedWindow) {
1318 // Stop iterating once we found a touched window. Any WATCH_OUTSIDE_TOUCH window
1319 // below the touched window will not get ACTION_OUTSIDE event.
1320 return outsideTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001321 }
1322
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001323 const WindowInfo& info = *windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001324 if (info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07001325 std::bitset<MAX_POINTER_ID + 1> pointerIds;
1326 pointerIds.set(pointerId);
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00001327 addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::OUTSIDE,
1328 ftl::Flags<InputTarget::Flags>(), pointerIds,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07001329 /*firstDownTimeInTarget=*/std::nullopt, outsideTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001330 }
1331 }
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001332 return outsideTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001333}
1334
Prabir Pradhand65552b2021-10-07 11:23:50 -07001335std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
Prabir Pradhan82e081e2022-12-06 09:50:09 +00001336 int32_t displayId, float x, float y, bool isStylus) const {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001337 // Traverse windows from front to back and gather the touched spy windows.
1338 std::vector<sp<WindowInfoHandle>> spyWindows;
1339 const auto& windowHandles = getWindowHandlesLocked(displayId);
1340 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1341 const WindowInfo& info = *windowHandle->getInfo();
1342
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00001343 if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001344 continue;
1345 }
1346 if (!info.isSpy()) {
1347 // The first touched non-spy window was found, so return the spy windows touched so far.
1348 return spyWindows;
1349 }
1350 spyWindows.push_back(windowHandle);
1351 }
1352 return spyWindows;
1353}
1354
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001355void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001356 const char* reason;
1357 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001358 case DropReason::POLICY:
Prabir Pradhan65613802023-02-22 23:36:58 +00001359 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001360 ALOGD("Dropped event because policy consumed it.");
1361 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001362 reason = "inbound event was dropped because the policy consumed it";
1363 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001364 case DropReason::DISABLED:
1365 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001366 ALOGI("Dropped event because input dispatch is disabled.");
1367 }
1368 reason = "inbound event was dropped because input dispatch is disabled";
1369 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001370 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001371 ALOGI("Dropped event because of pending overdue app switch.");
1372 reason = "inbound event was dropped because of pending overdue app switch";
1373 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001374 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001375 ALOGI("Dropped event because the current application is not responding and the user "
1376 "has started interacting with a different application.");
1377 reason = "inbound event was dropped because the current application is not responding "
1378 "and the user has started interacting with a different application";
1379 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001380 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001381 ALOGI("Dropped event because it is stale.");
1382 reason = "inbound event was dropped because it is stale";
1383 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001384 case DropReason::NO_POINTER_CAPTURE:
1385 ALOGI("Dropped event because there is no window with Pointer Capture.");
1386 reason = "inbound event was dropped because there is no window with Pointer Capture";
1387 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001388 case DropReason::NOT_DROPPED: {
1389 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001390 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001391 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001392 }
1393
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001394 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001395 case EventEntry::Type::KEY: {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001396 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS, reason);
Hu Guo3cfa7382023-11-15 09:50:04 +00001397 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1398 options.displayId = keyEntry.displayId;
1399 options.deviceId = keyEntry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001400 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001401 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001402 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001403 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001404 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1405 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001406 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, reason);
Hu Guo3cfa7382023-11-15 09:50:04 +00001407 options.displayId = motionEntry.displayId;
1408 options.deviceId = motionEntry.deviceId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001409 synthesizeCancelationEventsForAllConnectionsLocked(options);
1410 } else {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001411 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
1412 reason);
Hu Guo3cfa7382023-11-15 09:50:04 +00001413 options.displayId = motionEntry.displayId;
1414 options.deviceId = motionEntry.deviceId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001415 synthesizeCancelationEventsForAllConnectionsLocked(options);
1416 }
1417 break;
1418 }
Chris Yef59a2f42020-10-16 12:55:26 -07001419 case EventEntry::Type::SENSOR: {
1420 break;
1421 }
arthurhungb89ccb02020-12-30 16:19:01 +08001422 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1423 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001424 break;
1425 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001426 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001427 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001428 case EventEntry::Type::CONFIGURATION_CHANGED:
1429 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001430 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001431 break;
1432 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001433 }
1434}
1435
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001436static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001437 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1438 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001439}
1440
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001441bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1442 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1443 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1444 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001445}
1446
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07001447bool InputDispatcher::isAppSwitchPendingLocked() const {
Colin Cross5b799302022-10-18 21:52:41 -07001448 return mAppSwitchDueTime != LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001449}
1450
1451void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
Colin Cross5b799302022-10-18 21:52:41 -07001452 mAppSwitchDueTime = LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001453
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001454 if (DEBUG_APP_SWITCH) {
1455 if (handled) {
1456 ALOGD("App switch has arrived.");
1457 } else {
1458 ALOGD("App switch was abandoned.");
1459 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001460 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001461}
1462
Michael Wrightd02c5b62014-02-10 15:10:22 -08001463bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001464 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001465}
1466
Prabir Pradhancef936d2021-07-21 16:17:52 +00001467bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001468 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001469 return false;
1470 }
1471
1472 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001473 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001474 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001475 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1476 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001477 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001478 return true;
1479}
1480
Prabir Pradhancef936d2021-07-21 16:17:52 +00001481void InputDispatcher::postCommandLocked(Command&& command) {
1482 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001483}
1484
1485void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001486 while (!mInboundQueue.empty()) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001487 std::shared_ptr<const EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001488 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001489 releaseInboundEventLocked(entry);
1490 }
1491 traceInboundQueueLengthLocked();
1492}
1493
1494void InputDispatcher::releasePendingEventLocked() {
1495 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001496 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001497 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001498 }
1499}
1500
Prabir Pradhan24047542023-11-02 17:14:59 +00001501void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<const EventEntry> entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00001502 const std::shared_ptr<InjectionState>& injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001503 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001504 if (DEBUG_DISPATCH_CYCLE) {
1505 ALOGD("Injected inbound event was dropped.");
1506 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001507 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001508 }
1509 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001510 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001511 }
1512 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001513}
1514
1515void InputDispatcher::resetKeyRepeatLocked() {
1516 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001517 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001518 }
1519}
1520
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001521std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001522 std::shared_ptr<const KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001523
Michael Wright2e732952014-09-24 13:26:59 -07001524 uint32_t policyFlags = entry->policyFlags &
1525 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001526
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001527 std::shared_ptr<KeyEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00001528 std::make_unique<KeyEntry>(mIdGenerator.nextId(), /*injectionState=*/nullptr,
1529 currentTime, entry->deviceId, entry->source,
1530 entry->displayId, policyFlags, entry->action, entry->flags,
1531 entry->keyCode, entry->scanCode, entry->metaState,
1532 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001533
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001534 newEntry->syntheticRepeat = true;
1535 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001536 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001537 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001538}
1539
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001540bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001541 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001542 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1543 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1544 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001545
1546 // Reset key repeating in case a keyboard device was added or removed or something.
1547 resetKeyRepeatLocked();
1548
1549 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001550 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1551 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00001552 mPolicy.notifyConfigurationChanged(eventTime);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001553 };
1554 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001555 return true;
1556}
1557
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001558bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1559 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001560 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1561 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1562 entry.deviceId);
1563 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001564
liushenxiang42232912021-05-21 20:24:09 +08001565 // Reset key repeating in case a keyboard device was disabled or enabled.
1566 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1567 resetKeyRepeatLocked();
1568 }
1569
Michael Wrightfb04fd52022-11-24 22:31:11 +00001570 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001571 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001572 synthesizeCancelationEventsForAllConnectionsLocked(options);
Siarhei Vishniakou0686f0c2023-05-02 11:56:15 -07001573
1574 // Remove all active pointers from this device
1575 for (auto& [_, touchState] : mTouchStatesByDisplay) {
1576 touchState.removeAllPointersForDevice(entry.deviceId);
1577 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001578 return true;
1579}
1580
Vishnu Nairad321cd2020-08-20 16:40:21 -07001581void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001582 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001583 if (mPendingEvent != nullptr) {
1584 // Move the pending event to the front of the queue. This will give the chance
1585 // for the pending event to get dispatched to the newly focused window
1586 mInboundQueue.push_front(mPendingEvent);
1587 mPendingEvent = nullptr;
1588 }
1589
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001590 std::unique_ptr<FocusEntry> focusEntry =
1591 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1592 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001593
1594 // This event should go to the front of the queue, but behind all other focus events
1595 // Find the last focus event, and insert right after it
Prabir Pradhan24047542023-11-02 17:14:59 +00001596 auto it = std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
1597 [](const std::shared_ptr<const EventEntry>& event) {
1598 return event->type == EventEntry::Type::FOCUS;
1599 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001600
1601 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001602 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001603}
1604
Prabir Pradhan24047542023-11-02 17:14:59 +00001605void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime,
1606 std::shared_ptr<const FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001607 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001608 if (channel == nullptr) {
1609 return; // Window has gone away
1610 }
1611 InputTarget target;
1612 target.inputChannel = channel;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001613 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001614 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1615 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001616 std::string reason = std::string("reason=").append(entry->reason);
1617 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001618 dispatchEventLocked(currentTime, entry, {target});
1619}
1620
Prabir Pradhan99987712020-11-10 18:43:05 -08001621void InputDispatcher::dispatchPointerCaptureChangedLocked(
Prabir Pradhan24047542023-11-02 17:14:59 +00001622 nsecs_t currentTime, const std::shared_ptr<const PointerCaptureChangedEntry>& entry,
Prabir Pradhan99987712020-11-10 18:43:05 -08001623 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001624 dropReason = DropReason::NOT_DROPPED;
1625
Prabir Pradhan99987712020-11-10 18:43:05 -08001626 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001627 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001628
1629 if (entry->pointerCaptureRequest.enable) {
1630 // Enable Pointer Capture.
1631 if (haveWindowWithPointerCapture &&
1632 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
Prabir Pradhan7092e262022-05-03 16:51:09 +00001633 // This can happen if pointer capture is disabled and re-enabled before we notify the
1634 // app of the state change, so there is no need to notify the app.
1635 ALOGI("Skipping dispatch of Pointer Capture being enabled: no state change.");
1636 return;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001637 }
1638 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001639 // This can happen if a window requests capture and immediately releases capture.
1640 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001641 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001642 return;
1643 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001644 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1645 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1646 return;
1647 }
1648
Vishnu Nairc519ff72021-01-21 08:23:08 -08001649 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001650 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1651 mWindowTokenWithPointerCapture = token;
1652 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001653 // Disable Pointer Capture.
1654 // We do not check if the sequence number matches for requests to disable Pointer Capture
1655 // for two reasons:
1656 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1657 // to disable capture with the same sequence number: one generated by
1658 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1659 // Capture being disabled in InputReader.
1660 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1661 // actual Pointer Capture state that affects events being generated by input devices is
1662 // in InputReader.
1663 if (!haveWindowWithPointerCapture) {
1664 // Pointer capture was already forcefully disabled because of focus change.
1665 dropReason = DropReason::NOT_DROPPED;
1666 return;
1667 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001668 token = mWindowTokenWithPointerCapture;
1669 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001670 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001671 setPointerCaptureLocked(false);
1672 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001673 }
1674
1675 auto channel = getInputChannelLocked(token);
1676 if (channel == nullptr) {
1677 // Window has gone away, clean up Pointer Capture state.
1678 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001679 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001680 setPointerCaptureLocked(false);
1681 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001682 return;
1683 }
1684 InputTarget target;
1685 target.inputChannel = channel;
Prabir Pradhan99987712020-11-10 18:43:05 -08001686 entry->dispatchInProgress = true;
1687 dispatchEventLocked(currentTime, entry, {target});
1688
1689 dropReason = DropReason::NOT_DROPPED;
1690}
1691
Prabir Pradhan24047542023-11-02 17:14:59 +00001692void InputDispatcher::dispatchTouchModeChangeLocked(
1693 nsecs_t currentTime, const std::shared_ptr<const TouchModeEntry>& entry) {
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001694 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Antonio Kantek15beb512022-06-13 22:35:41 +00001695 getWindowHandlesLocked(entry->displayId);
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001696 if (windowHandles.empty()) {
1697 return;
1698 }
1699 const std::vector<InputTarget> inputTargets =
1700 getInputTargetsFromWindowHandlesLocked(windowHandles);
1701 if (inputTargets.empty()) {
1702 return;
1703 }
1704 entry->dispatchInProgress = true;
1705 dispatchEventLocked(currentTime, entry, inputTargets);
1706}
1707
1708std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1709 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1710 std::vector<InputTarget> inputTargets;
1711 for (const sp<WindowInfoHandle>& handle : windowHandles) {
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001712 const sp<IBinder>& token = handle->getToken();
1713 if (token == nullptr) {
1714 continue;
1715 }
1716 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1717 if (channel == nullptr) {
1718 continue; // Window has gone away
1719 }
1720 InputTarget target;
1721 target.inputChannel = channel;
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001722 inputTargets.push_back(target);
1723 }
1724 return inputTargets;
1725}
1726
Prabir Pradhan24047542023-11-02 17:14:59 +00001727bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001728 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001729 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001730 if (!entry->dispatchInProgress) {
1731 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1732 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1733 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1734 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001735 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001736 // We have seen two identical key downs in a row which indicates that the device
1737 // driver is automatically generating key repeats itself. We take note of the
1738 // repeat here, but we disable our own next key repeat timer since it is clear that
1739 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001740 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1741 // Make sure we don't get key down from a different device. If a different
1742 // device Id has same key pressed down, the new device Id will replace the
1743 // current one to hold the key repeat with repeat count reset.
1744 // In the future when got a KEY_UP on the device id, drop it and do not
1745 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001746 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1747 resetKeyRepeatLocked();
Colin Cross5b799302022-10-18 21:52:41 -07001748 mKeyRepeatState.nextRepeatTime = LLONG_MAX; // don't generate repeats ourselves
Michael Wrightd02c5b62014-02-10 15:10:22 -08001749 } else {
1750 // Not a repeat. Save key down state in case we do see a repeat later.
1751 resetKeyRepeatLocked();
1752 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1753 }
1754 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001755 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1756 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001757 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan65613802023-02-22 23:36:58 +00001758 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001759 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1760 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001761 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001762 resetKeyRepeatLocked();
1763 }
1764
1765 if (entry->repeatCount == 1) {
1766 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1767 } else {
1768 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1769 }
1770
1771 entry->dispatchInProgress = true;
1772
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001773 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001774 }
1775
1776 // Handle case where the policy asked us to try again later last time.
Michael Wright5caf55a2022-11-24 22:31:42 +00001777 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001778 if (currentTime < entry->interceptKeyWakeupTime) {
1779 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1780 *nextWakeupTime = entry->interceptKeyWakeupTime;
1781 }
1782 return false; // wait until next wakeup
1783 }
Michael Wright5caf55a2022-11-24 22:31:42 +00001784 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001785 entry->interceptKeyWakeupTime = 0;
1786 }
1787
1788 // Give the policy a chance to intercept the key.
Michael Wright5caf55a2022-11-24 22:31:42 +00001789 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001790 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001791 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001792 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001793
1794 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1795 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1796 };
1797 postCommandLocked(std::move(command));
Josep del Riob3981622023-04-18 15:49:45 +00001798 // Poke user activity for keys not passed to user
1799 pokeUserActivityLocked(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001800 return false; // wait for the command to run
1801 } else {
Michael Wright5caf55a2022-11-24 22:31:42 +00001802 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001803 }
Michael Wright5caf55a2022-11-24 22:31:42 +00001804 } else if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001805 if (*dropReason == DropReason::NOT_DROPPED) {
1806 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001807 }
1808 }
1809
1810 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001811 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001812 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001813 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1814 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001815 mReporter->reportDroppedKey(entry->id);
Josep del Riob3981622023-04-18 15:49:45 +00001816 // Poke user activity for undispatched keys
1817 pokeUserActivityLocked(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001818 return true;
1819 }
1820
1821 // Identify targets.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001822 InputEventInjectionResult injectionResult;
1823 sp<WindowInfoHandle> focusedWindow =
1824 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime,
1825 /*byref*/ injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001826 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001827 return false;
1828 }
1829
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001830 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001831 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001832 return true;
1833 }
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001834 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
1835
1836 std::vector<InputTarget> inputTargets;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00001837 addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
1838 InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001839
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001840 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001841 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001842
1843 // Dispatch the key.
1844 dispatchEventLocked(currentTime, entry, inputTargets);
1845 return true;
1846}
1847
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001848void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001849 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1850 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1851 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1852 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1853 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1854 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1855 entry.metaState, entry.repeatCount, entry.downTime);
1856 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001857}
1858
Prabir Pradhancef936d2021-07-21 16:17:52 +00001859void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
Prabir Pradhan24047542023-11-02 17:14:59 +00001860 const std::shared_ptr<const SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001861 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001862 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1863 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1864 "source=0x%x, sensorType=%s",
1865 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001866 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001867 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001868 auto command = [this, entry]() REQUIRES(mLock) {
1869 scoped_unlock unlock(mLock);
1870
1871 if (entry->accuracyChanged) {
Prabir Pradhana41d2442023-04-20 21:30:40 +00001872 mPolicy.notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001873 }
Prabir Pradhana41d2442023-04-20 21:30:40 +00001874 mPolicy.notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1875 entry->hwTimestamp, entry->values);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001876 };
1877 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001878}
1879
1880bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001881 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1882 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001883 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001884 }
Chris Yef59a2f42020-10-16 12:55:26 -07001885 { // acquire lock
1886 std::scoped_lock _l(mLock);
1887
1888 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001889 std::shared_ptr<const EventEntry> entry = *it;
Chris Yef59a2f42020-10-16 12:55:26 -07001890 if (entry->type == EventEntry::Type::SENSOR) {
1891 it = mInboundQueue.erase(it);
1892 releaseInboundEventLocked(entry);
1893 }
1894 }
1895 }
1896 return true;
1897}
1898
Prabir Pradhan24047542023-11-02 17:14:59 +00001899bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime,
1900 std::shared_ptr<const MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001901 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001902 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001903 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001904 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001905 entry->dispatchInProgress = true;
1906
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001907 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001908 }
1909
1910 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001911 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001912 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001913 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1914 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001915 return true;
1916 }
1917
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001918 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001919
1920 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001921 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001922
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001923 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001924 if (isPointerEvent) {
1925 // Pointer event. (eg. touchscreen)
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00001926
1927 if (mDragState &&
1928 (entry->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN) {
1929 // If drag and drop ongoing and pointer down occur: pilfer drag window pointers
1930 pilferPointersLocked(mDragState->dragWindow->getToken());
1931 }
1932
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08001933 inputTargets =
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07001934 findTouchedWindowTargetsLocked(currentTime, *entry, /*byref*/ injectionResult);
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08001935 LOG_ALWAYS_FATAL_IF(injectionResult != InputEventInjectionResult::SUCCEEDED &&
1936 !inputTargets.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001937 } else {
1938 // Non touch event. (eg. trackball)
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001939 sp<WindowInfoHandle> focusedWindow =
1940 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime, injectionResult);
1941 if (injectionResult == InputEventInjectionResult::SUCCEEDED) {
1942 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00001943 addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
1944 InputTarget::Flags::FOREGROUND, getDownTime(*entry),
1945 inputTargets);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001946 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001947 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001948 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001949 return false;
1950 }
1951
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001952 setInjectionResult(*entry, injectionResult);
Prabir Pradhan5735a322022-04-11 17:23:34 +00001953 if (injectionResult == InputEventInjectionResult::TARGET_MISMATCH) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001954 return true;
1955 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001956 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001957 CancelationOptions::Mode mode(
1958 isPointerEvent ? CancelationOptions::Mode::CANCEL_POINTER_EVENTS
1959 : CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS);
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001960 CancelationOptions options(mode, "input event injection failed");
1961 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001962 return true;
1963 }
1964
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001965 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001966 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001967
1968 // Dispatch the motion.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001969 dispatchEventLocked(currentTime, entry, inputTargets);
1970 return true;
1971}
1972
chaviw98318de2021-05-19 16:45:23 -05001973void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
Arthur Hung54745652022-04-20 07:17:41 +00001974 bool isExiting, const int32_t rawX,
1975 const int32_t rawY) {
1976 const vec2 xy = windowHandle->getInfo()->transform.transform(vec2(rawX, rawY));
arthurhungb89ccb02020-12-30 16:19:01 +08001977 std::unique_ptr<DragEntry> dragEntry =
Arthur Hung54745652022-04-20 07:17:41 +00001978 std::make_unique<DragEntry>(mIdGenerator.nextId(), now(), windowHandle->getToken(),
1979 isExiting, xy.x, xy.y);
arthurhungb89ccb02020-12-30 16:19:01 +08001980
1981 enqueueInboundEventLocked(std::move(dragEntry));
1982}
1983
Prabir Pradhan24047542023-11-02 17:14:59 +00001984void InputDispatcher::dispatchDragLocked(nsecs_t currentTime,
1985 std::shared_ptr<const DragEntry> entry) {
arthurhungb89ccb02020-12-30 16:19:01 +08001986 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1987 if (channel == nullptr) {
1988 return; // Window has gone away
1989 }
1990 InputTarget target;
1991 target.inputChannel = channel;
arthurhungb89ccb02020-12-30 16:19:01 +08001992 entry->dispatchInProgress = true;
1993 dispatchEventLocked(currentTime, entry, {target});
1994}
1995
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001996void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001997 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08001998 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=%s, displayId=%" PRId32
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001999 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00002000 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002001 "metaState=0x%x, buttonState=0x%x,"
2002 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08002003 prefix, entry.eventTime, entry.deviceId,
2004 inputEventSourceToString(entry.source).c_str(), entry.displayId, entry.policyFlags,
2005 MotionEvent::actionToString(entry.action).c_str(), entry.actionButton, entry.flags,
2006 entry.metaState, entry.buttonState, entry.edgeFlags, entry.xPrecision,
2007 entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002008
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002009 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002010 ALOGD(" Pointer %d: id=%d, toolType=%s, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002011 "x=%f, y=%f, pressure=%f, size=%f, "
2012 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2013 "orientation=%f",
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -07002014 i, entry.pointerProperties[i].id,
2015 ftl::enum_string(entry.pointerProperties[i].toolType).c_str(),
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002016 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2017 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2018 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2019 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2020 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2021 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2022 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2023 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2024 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2025 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002026 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002027}
2028
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002029void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
Prabir Pradhan24047542023-11-02 17:14:59 +00002030 std::shared_ptr<const EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002031 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002032 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002033 if (DEBUG_DISPATCH_CYCLE) {
2034 ALOGD("dispatchEventToCurrentInputTargets");
2035 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002036
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00002037 processInteractionsLocked(*eventEntry, inputTargets);
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002038
Michael Wrightd02c5b62014-02-10 15:10:22 -08002039 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
2040
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002041 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002042
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002043 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002044 std::shared_ptr<Connection> connection =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002045 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002046 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002047 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002048 } else {
Siarhei Vishniakou31dd1552023-10-30 18:46:10 -07002049 if (DEBUG_DROPPED_EVENTS_VERBOSE) {
2050 LOG(INFO) << "Dropping event delivery to target with channel "
2051 << inputTarget.inputChannel->getName()
2052 << " because it is no longer registered with the input dispatcher.";
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002053 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002054 }
2055 }
2056}
2057
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002058void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002059 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
2060 // If the policy decides to close the app, we will get a channel removal event via
2061 // unregisterInputChannel, and will clean up the connection that way. We are already not
2062 // sending new pointers to the connection when it blocked, but focused events will continue to
2063 // pile up.
2064 ALOGW("Canceling events for %s because it is unresponsive",
2065 connection->inputChannel->getName().c_str());
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002066 if (connection->status == Connection::Status::NORMAL) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00002067 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002068 "application not responding");
2069 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002070 }
2071}
2072
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002073void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002074 if (DEBUG_FOCUS) {
2075 ALOGD("Resetting ANR timeouts.");
2076 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002077
2078 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002079 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07002080 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002081}
2082
Tiger Huang721e26f2018-07-24 22:26:19 +08002083/**
2084 * Get the display id that the given event should go to. If this event specifies a valid display id,
2085 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
2086 * Focused display is the display that the user most recently interacted with.
2087 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002088int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08002089 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002090 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002091 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002092 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2093 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002094 break;
2095 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002096 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002097 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2098 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002099 break;
2100 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002101 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002102 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002103 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002104 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07002105 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08002106 case EventEntry::Type::SENSOR:
2107 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08002108 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002109 return ADISPLAY_ID_NONE;
2110 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002111 }
2112 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
2113}
2114
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002115bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
2116 const char* focusedWindowName) {
2117 if (mAnrTracker.empty()) {
2118 // already processed all events that we waited for
2119 mKeyIsWaitingForEventsTimeout = std::nullopt;
2120 return false;
2121 }
2122
2123 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
2124 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002125 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002126 mKeyIsWaitingForEventsTimeout = currentTime +
2127 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
2128 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002129 return true;
2130 }
2131
2132 // We still have pending events, and already started the timer
2133 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
2134 return true; // Still waiting
2135 }
2136
2137 // Waited too long, and some connection still hasn't processed all motions
2138 // Just send the key to the focused window
2139 ALOGW("Dispatching key to %s even though there are other unprocessed events",
2140 focusedWindowName);
2141 mKeyIsWaitingForEventsTimeout = std::nullopt;
2142 return false;
2143}
2144
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002145sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked(
2146 nsecs_t currentTime, const EventEntry& entry, nsecs_t* nextWakeupTime,
2147 InputEventInjectionResult& outInjectionResult) {
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002148 outInjectionResult = InputEventInjectionResult::FAILED; // Default result
Michael Wrightd02c5b62014-02-10 15:10:22 -08002149
Tiger Huang721e26f2018-07-24 22:26:19 +08002150 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05002151 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07002152 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08002153 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
2154
Michael Wrightd02c5b62014-02-10 15:10:22 -08002155 // If there is no currently focused window and no focused application
2156 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002157 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
2158 ALOGI("Dropping %s event because there is no focused window or focused application in "
2159 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08002160 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002161 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002162 }
2163
Vishnu Nair062a8672021-09-03 16:07:44 -07002164 // Drop key events if requested by input feature
2165 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002166 return nullptr;
Vishnu Nair062a8672021-09-03 16:07:44 -07002167 }
2168
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002169 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
2170 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
2171 // start interacting with another application via touch (app switch). This code can be removed
2172 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
2173 // an app is expected to have a focused window.
2174 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
2175 if (!mNoFocusedWindowTimeoutTime.has_value()) {
2176 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05002177 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
2178 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
2179 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002180 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05002181 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002182 ALOGW("Waiting because no window has focus but %s may eventually add a "
2183 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05002184 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002185 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002186 outInjectionResult = InputEventInjectionResult::PENDING;
2187 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002188 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
2189 // Already raised ANR. Drop the event
2190 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08002191 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002192 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002193 } else {
2194 // Still waiting for the focused window
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002195 outInjectionResult = InputEventInjectionResult::PENDING;
2196 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002197 }
2198 }
2199
2200 // we have a valid, non-null focused window
2201 resetNoFocusedWindowTimeoutLocked();
2202
Prabir Pradhan5735a322022-04-11 17:23:34 +00002203 // Verify targeted injection.
2204 if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) {
2205 ALOGW("Dropping injected event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002206 outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
2207 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002208 }
2209
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002210 if (focusedWindowHandle->getInfo()->inputConfig.test(
2211 WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002212 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002213 outInjectionResult = InputEventInjectionResult::PENDING;
2214 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002215 }
2216
2217 // If the event is a key event, then we must wait for all previous events to
2218 // complete before delivering it because previous events may have the
2219 // side-effect of transferring focus to a different window and we want to
2220 // ensure that the following keys are sent to the new window.
2221 //
2222 // Suppose the user touches a button in a window then immediately presses "A".
2223 // If the button causes a pop-up window to appear then we want to ensure that
2224 // the "A" key is delivered to the new pop-up window. This is because users
2225 // often anticipate pending UI changes when typing on a keyboard.
2226 // To obtain this behavior, we must serialize key events with respect to all
2227 // prior input events.
2228 if (entry.type == EventEntry::Type::KEY) {
2229 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
2230 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002231 outInjectionResult = InputEventInjectionResult::PENDING;
2232 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002233 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002234 }
2235
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002236 outInjectionResult = InputEventInjectionResult::SUCCEEDED;
2237 return focusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002238}
2239
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002240/**
2241 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
2242 * that are currently unresponsive.
2243 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002244std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
2245 const std::vector<Monitor>& monitors) const {
2246 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002247 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002248 [this](const Monitor& monitor) REQUIRES(mLock) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002249 std::shared_ptr<Connection> connection =
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002250 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002251 if (connection == nullptr) {
2252 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002253 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002254 return false;
2255 }
2256 if (!connection->responsive) {
2257 ALOGW("Unresponsive monitor %s will not get the new gesture",
2258 connection->inputChannel->getName().c_str());
2259 return false;
2260 }
2261 return true;
2262 });
2263 return responsiveMonitors;
2264}
2265
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002266std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002267 nsecs_t currentTime, const MotionEntry& entry,
Siarhei Vishniakou4fe57392022-10-25 13:44:30 -07002268 InputEventInjectionResult& outInjectionResult) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002269 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002270
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002271 std::vector<InputTarget> targets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002272 // For security reasons, we defer updating the touch state until we are sure that
2273 // event injection will be allowed.
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002274 const int32_t displayId = entry.displayId;
2275 const int32_t action = entry.action;
Siarhei Vishniakoubf880522023-05-01 11:03:22 -07002276 const int32_t maskedAction = MotionEvent::getActionMasked(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002277
2278 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002279 outInjectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002280
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002281 // Copy current touch state into tempTouchState.
2282 // This state will be used to update mTouchStatesByDisplay at the end of this function.
2283 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07002284 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002285 TouchState tempTouchState;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002286 if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
2287 oldState = &(it->second);
Prabir Pradhane680f9b2022-02-04 04:24:00 -08002288 tempTouchState = *oldState;
Jeff Brownf086ddb2014-02-11 14:28:48 -08002289 }
2290
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002291 bool isSplit = shouldSplitTouch(tempTouchState, entry);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002292
2293 const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2294 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2295 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002296 // A DOWN could be generated from POINTER_DOWN if the initial pointers did not land into any
2297 // touchable windows.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002298 const bool wasDown = oldState != nullptr && oldState->isDown(entry.deviceId);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002299 const bool isDown = (maskedAction == AMOTION_EVENT_ACTION_DOWN) ||
2300 (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN && !wasDown);
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002301 const bool newGesture = isDown || maskedAction == AMOTION_EVENT_ACTION_SCROLL ||
2302 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2303 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE;
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002304 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Siarhei Vishniakou5cee1e32022-11-29 12:35:39 -08002305
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002306 if (newGesture) {
2307 isSplit = false;
Siarhei Vishniakouf372b812023-02-14 18:06:51 -08002308 }
2309
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002310 if (isDown && tempTouchState.hasHoveringPointers(entry.deviceId)) {
2311 // Compatibility behaviour: ACTION_DOWN causes HOVER_EXIT to get generated.
2312 tempTouchState.clearHoveringPointers(entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002313 }
2314
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002315 if (isHoverAction) {
Siarhei Vishniakou7be50c92023-11-17 17:09:08 -08002316 if (wasDown) {
2317 // Started hovering, but the device is already down: reject the hover event
2318 LOG(ERROR) << "Got hover event " << entry.getDescription()
2319 << " but the device is already down " << oldState->dump();
2320 outInjectionResult = InputEventInjectionResult::FAILED;
2321 return {};
2322 }
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002323 // For hover actions, we will treat 'tempTouchState' as a new state, so let's erase
2324 // all of the existing hovering pointers and recompute.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002325 tempTouchState.clearHoveringPointers(entry.deviceId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002326 }
2327
Michael Wrightd02c5b62014-02-10 15:10:22 -08002328 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2329 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07002330 const auto [x, y] = resolveTouchedPosition(entry);
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002331 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07002332 const int32_t pointerId = entry.pointerProperties[pointerIndex].id;
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002333 // Outside targets should be added upon first dispatched DOWN event. That means, this should
2334 // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down.
Prabir Pradhand65552b2021-10-07 11:23:50 -07002335 const bool isStylus = isPointerFromStylus(entry, pointerIndex);
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002336 sp<WindowInfoHandle> newTouchedWindowHandle =
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002337 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Michael Wright3dd60e22019-03-27 22:06:44 +00002338
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002339 if (isDown) {
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07002340 targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointerId);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002341 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002342 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002343 if (newTouchedWindowHandle == nullptr) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00002344 ALOGD("No new touched window at (%.1f, %.1f) in display %" PRId32, x, y, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002345 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002346 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002347 }
2348
Prabir Pradhan5735a322022-04-11 17:23:34 +00002349 // Verify targeted injection.
2350 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2351 ALOGW("Dropping injected touch event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002352 outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
Prabir Pradhan5735a322022-04-11 17:23:34 +00002353 newTouchedWindowHandle = nullptr;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002354 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002355 }
2356
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002357 // Figure out whether splitting will be allowed for this window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002358 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002359 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2360 // New window supports splitting, but we should never split mouse events.
2361 isSplit = !isFromMouse;
2362 } else if (isSplit) {
2363 // New window does not support splitting but we have already split events.
2364 // Ignore the new window.
Siarhei Vishniakou25537f82023-07-18 14:35:47 -07002365 LOG(INFO) << "Skipping " << newTouchedWindowHandle->getName()
2366 << " because it doesn't support split touch";
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002367 newTouchedWindowHandle = nullptr;
2368 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002369 } else {
2370 // No window is touched, so set split to true. This will allow the next pointer down to
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002371 // be delivered to a new window which supports split touch. Pointers from a mouse device
2372 // should never be split.
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002373 isSplit = !isFromMouse;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002374 }
2375
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002376 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002377 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002378 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002379 // Process the foreground window first so that it is the first to receive the event.
2380 newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002381 }
2382
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002383 if (newTouchedWindows.empty()) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00002384 ALOGI("Dropping event because there is no touchable window at (%.1f, %.1f) on display "
2385 "%d.",
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002386 x, y, displayId);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002387 outInjectionResult = InputEventInjectionResult::FAILED;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002388 return {};
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002389 }
2390
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002391 for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07002392 if (!canWindowReceiveMotionLocked(windowHandle, entry)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002393 continue;
2394 }
2395
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002396 if (isHoverAction) {
Siarhei Vishniakoub681c202023-05-01 11:22:33 -07002397 // The "windowHandle" is the target of this hovering pointer.
2398 tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointerId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002399 }
2400
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002401 // Set target flags.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002402 ftl::Flags<InputTarget::Flags> targetFlags;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002403
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002404 if (canReceiveForegroundTouches(*windowHandle->getInfo())) {
2405 // There should only be one touched window that can be "foreground" for the pointer.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002406 targetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002407 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002408
2409 if (isSplit) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002410 targetFlags |= InputTarget::Flags::SPLIT;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002411 }
2412 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002413 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002414 } else if (isWindowObscuredLocked(windowHandle)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002415 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002416 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002417
2418 // Update the temporary touch state.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002419
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002420 if (!isHoverAction) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002421 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07002422 pointerIds.set(pointerId);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002423 const bool isDownOrPointerDown = maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2424 maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002425 tempTouchState.addOrUpdateWindow(windowHandle, InputTarget::DispatchMode::AS_IS,
2426 targetFlags, entry.deviceId, pointerIds,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002427 isDownOrPointerDown
2428 ? std::make_optional(entry.eventTime)
2429 : std::nullopt);
2430 // If this is the pointer going down and the touched window has a wallpaper
2431 // then also add the touched wallpaper windows so they are locked in for the
2432 // duration of the touch gesture. We do not collect wallpapers during HOVER_MOVE or
2433 // SCROLL because the wallpaper engine only supports touch events. We would need to
2434 // add a mechanism similar to View.onGenericMotionEvent to enable wallpapers to
2435 // handle these events.
2436 if (isDownOrPointerDown && targetFlags.test(InputTarget::Flags::FOREGROUND) &&
Arthur Hungc539dbb2022-12-08 07:45:36 +00002437 windowHandle->getInfo()->inputConfig.test(
2438 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
2439 sp<WindowInfoHandle> wallpaper = findWallpaperWindowBelow(windowHandle);
2440 if (wallpaper != nullptr) {
2441 ftl::Flags<InputTarget::Flags> wallpaperFlags =
2442 InputTarget::Flags::WINDOW_IS_OBSCURED |
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002443 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Arthur Hungc539dbb2022-12-08 07:45:36 +00002444 if (isSplit) {
2445 wallpaperFlags |= InputTarget::Flags::SPLIT;
2446 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002447 tempTouchState.addOrUpdateWindow(wallpaper,
2448 InputTarget::DispatchMode::AS_IS,
2449 wallpaperFlags, entry.deviceId, pointerIds,
2450 entry.eventTime);
Arthur Hungc539dbb2022-12-08 07:45:36 +00002451 }
2452 }
2453 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002454 }
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00002455
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002456 // If a window is already pilfering some pointers, give it this new pointer as well and
2457 // make it pilfering. This will prevent other non-spy windows from getting this pointer,
2458 // which is a specific behaviour that we want.
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002459 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002460 if (touchedWindow.hasTouchingPointer(entry.deviceId, pointerId) &&
2461 touchedWindow.hasPilferingPointers(entry.deviceId)) {
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002462 // This window is already pilfering some pointers, and this new pointer is also
2463 // going to it. Therefore, take over this pointer and don't give it to anyone
2464 // else.
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002465 touchedWindow.addPilferingPointer(entry.deviceId, pointerId);
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00002466 }
2467 }
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002468
2469 // Restrict all pilfered pointers to the pilfering windows.
2470 tempTouchState.cancelPointersForNonPilferingWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002471 } else {
2472 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2473
2474 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002475 if (!tempTouchState.isDown(entry.deviceId) &&
2476 maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) {
Siarhei Vishniakou31dd1552023-10-30 18:46:10 -07002477 if (DEBUG_DROPPED_EVENTS_VERBOSE) {
2478 LOG(INFO) << "Dropping event because the pointer for device " << entry.deviceId
2479 << " is not down or we previously dropped the pointer down event in "
2480 << "display " << displayId << ": " << entry.getDescription();
2481 }
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002482 outInjectionResult = InputEventInjectionResult::FAILED;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002483 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002484 }
2485
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002486 // If the pointer is not currently hovering, then ignore the event.
2487 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2488 const int32_t pointerId = entry.pointerProperties[0].id;
2489 if (oldState == nullptr ||
2490 oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId).empty()) {
2491 LOG(INFO) << "Dropping event because the hovering pointer is not in any windows in "
2492 "display "
2493 << displayId << ": " << entry.getDescription();
2494 outInjectionResult = InputEventInjectionResult::FAILED;
2495 return {};
2496 }
2497 tempTouchState.removeHoveringPointer(entry.deviceId, pointerId);
2498 }
2499
arthurhung6d4bed92021-03-17 11:59:33 +08002500 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002501
Michael Wrightd02c5b62014-02-10 15:10:22 -08002502 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002503 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.getPointerCount() == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002504 tempTouchState.isSlippery()) {
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07002505 const auto [x, y] = resolveTouchedPosition(entry);
Harry Cutts33476232023-01-30 19:57:29 +00002506 const bool isStylus = isPointerFromStylus(entry, /*pointerIndex=*/0);
chaviw98318de2021-05-19 16:45:23 -05002507 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002508 tempTouchState.getFirstForegroundWindowHandle();
Siarhei Vishniakou0f6558d2023-04-21 12:05:13 -07002509 LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr);
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002510 sp<WindowInfoHandle> newTouchedWindowHandle =
2511 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Vishnu Nair062a8672021-09-03 16:07:44 -07002512
Prabir Pradhan5735a322022-04-11 17:23:34 +00002513 // Verify targeted injection.
2514 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2515 ALOGW("Dropping injected event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002516 outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002517 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002518 }
2519
Vishnu Nair062a8672021-09-03 16:07:44 -07002520 // Drop touch events if requested by input feature
2521 if (newTouchedWindowHandle != nullptr &&
2522 shouldDropInput(entry, newTouchedWindowHandle)) {
2523 newTouchedWindowHandle = nullptr;
2524 }
2525
Siarhei Vishniakouafa08cc2023-05-08 22:35:50 -07002526 if (newTouchedWindowHandle != nullptr &&
2527 !haveSameToken(oldTouchedWindowHandle, newTouchedWindowHandle)) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002528 ALOGI("Touch is slipping out of window %s into window %s in display %" PRId32,
Siarhei Vishniakou0f6558d2023-04-21 12:05:13 -07002529 oldTouchedWindowHandle->getName().c_str(),
2530 newTouchedWindowHandle->getName().c_str(), displayId);
2531
Michael Wrightd02c5b62014-02-10 15:10:22 -08002532 // Make a slippery exit from the old window.
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08002533 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002534 const int32_t pointerId = entry.pointerProperties[0].id;
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08002535 pointerIds.set(pointerId);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002536
2537 const TouchedWindow& touchedWindow =
2538 tempTouchState.getTouchedWindow(oldTouchedWindowHandle);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002539 addPointerWindowTargetLocked(oldTouchedWindowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002540 InputTarget::DispatchMode::SLIPPERY_EXIT,
2541 ftl::Flags<InputTarget::Flags>(), pointerIds,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002542 touchedWindow.getDownTimeInTarget(entry.deviceId),
2543 targets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002544
2545 // Make a slippery entrance into the new window.
2546 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002547 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002548 }
2549
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002550 ftl::Flags<InputTarget::Flags> targetFlags;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002551 if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002552 targetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002553 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002554 if (isSplit) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002555 targetFlags |= InputTarget::Flags::SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002556 }
2557 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002558 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002559 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002560 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002561 }
2562
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002563 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle,
2564 InputTarget::DispatchMode::SLIPPERY_ENTER,
2565 targetFlags, entry.deviceId, pointerIds,
2566 entry.eventTime);
Arthur Hungc539dbb2022-12-08 07:45:36 +00002567
2568 // Check if the wallpaper window should deliver the corresponding event.
2569 slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002570 tempTouchState, entry.deviceId, pointerId, targets);
2571 tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointerId,
2572 oldTouchedWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002573 }
2574 }
Arthur Hung96483742022-11-15 03:30:48 +00002575
2576 // Update the pointerIds for non-splittable when it received pointer down.
2577 if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2578 // If no split, we suppose all touched windows should receive pointer down.
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002579 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
Arthur Hung96483742022-11-15 03:30:48 +00002580 for (size_t i = 0; i < tempTouchState.windows.size(); i++) {
2581 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2582 // Ignore drag window for it should just track one pointer.
2583 if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
2584 continue;
2585 }
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002586 std::bitset<MAX_POINTER_ID + 1> touchingPointers;
2587 touchingPointers.set(entry.pointerProperties[pointerIndex].id);
2588 touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers);
Arthur Hung96483742022-11-15 03:30:48 +00002589 }
2590 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002591 }
2592
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002593 // Update dispatching for hover enter and exit.
Sam Dubeyf886dec2023-01-27 13:28:19 +00002594 {
2595 std::vector<TouchedWindow> hoveringWindows =
2596 getHoveringWindowsLocked(oldState, tempTouchState, entry);
2597 for (const TouchedWindow& touchedWindow : hoveringWindows) {
Siarhei Vishniakoud5876ba2023-05-15 17:58:34 -07002598 std::optional<InputTarget> target =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002599 createInputTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
2600 touchedWindow.targetFlags,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002601 touchedWindow.getDownTimeInTarget(entry.deviceId));
Siarhei Vishniakoud5876ba2023-05-15 17:58:34 -07002602 if (!target) {
2603 continue;
2604 }
2605 // Hardcode to single hovering pointer for now.
2606 std::bitset<MAX_POINTER_ID + 1> pointerIds;
2607 pointerIds.set(entry.pointerProperties[0].id);
2608 target->addPointers(pointerIds, touchedWindow.windowHandle->getInfo()->transform);
2609 targets.push_back(*target);
Sam Dubeyf886dec2023-01-27 13:28:19 +00002610 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002611 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002612
Prabir Pradhan5735a322022-04-11 17:23:34 +00002613 // Ensure that all touched windows are valid for injection.
2614 if (entry.injectionState != nullptr) {
2615 std::string errs;
2616 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Prabir Pradhan5735a322022-04-11 17:23:34 +00002617 const auto err = verifyTargetedInjection(touchedWindow.windowHandle, entry);
2618 if (err) errs += "\n - " + *err;
2619 }
2620 if (!errs.empty()) {
2621 ALOGW("Dropping targeted injection: At least one touched window is not owned by uid "
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00002622 "%s:%s",
2623 entry.injectionState->targetUid->toString().c_str(), errs.c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002624 outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002625 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002626 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002627 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002628
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002629 // Check whether windows listening for outside touches are owned by the same UID. If the owner
2630 // has a different UID, then we will not reveal coordinate information to this window.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002631 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002632 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002633 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002634 if (foregroundWindowHandle) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00002635 const auto foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002636 for (InputTarget& target : targets) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002637 if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002638 sp<WindowInfoHandle> targetWindow =
2639 getWindowHandleLocked(target.inputChannel->getConnectionToken());
2640 if (targetWindow->getInfo()->ownerUid != foregroundWindowUid) {
2641 target.flags |= InputTarget::Flags::ZERO_COORDS;
Michael Wright3dd60e22019-03-27 22:06:44 +00002642 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002643 }
2644 }
2645 }
2646 }
2647
Harry Cuttsb166c002023-05-09 13:06:05 +00002648 // If this is a touchpad navigation gesture, it needs to only be sent to trusted targets, as we
2649 // only want the system UI to handle these gestures.
2650 const bool isTouchpadNavGesture = isFromSource(entry.source, AINPUT_SOURCE_MOUSE) &&
2651 entry.classification == MotionClassification::MULTI_FINGER_SWIPE;
2652 if (isTouchpadNavGesture) {
2653 filterUntrustedTargets(/* byref */ tempTouchState, /* byref */ targets);
2654 }
2655
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002656 // Output targets from the touch state.
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002657 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002658 std::bitset<MAX_POINTER_ID + 1> touchingPointers =
2659 touchedWindow.getTouchingPointers(entry.deviceId);
2660 if (touchingPointers.none()) {
Siarhei Vishniakoue0431e42023-01-28 17:01:39 -08002661 continue;
2662 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002663 addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
2664 touchedWindow.targetFlags, touchingPointers,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002665 touchedWindow.getDownTimeInTarget(entry.deviceId), targets);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002666 }
Sam Dubey39d37cf2022-12-07 18:05:35 +00002667
Siarhei Vishniakou580fb3a2023-05-05 15:02:20 -07002668 // During targeted injection, only allow owned targets to receive events
2669 std::erase_if(targets, [&](const InputTarget& target) {
2670 LOG_ALWAYS_FATAL_IF(target.windowHandle == nullptr);
2671 const auto err = verifyTargetedInjection(target.windowHandle, entry);
2672 if (err) {
2673 LOG(WARNING) << "Dropping injected event from " << target.windowHandle->getName()
2674 << ": " << (*err);
2675 return true;
2676 }
2677 return false;
2678 });
2679
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002680 if (targets.empty()) {
2681 LOG(INFO) << "Dropping event because no targets were found: " << entry.getDescription();
2682 outInjectionResult = InputEventInjectionResult::FAILED;
2683 return {};
2684 }
2685
2686 // If we only have windows getting ACTION_OUTSIDE, then drop the event, because there is no
2687 // window that is actually receiving the entire gesture.
2688 if (std::all_of(targets.begin(), targets.end(), [](const InputTarget& target) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002689 return target.dispatchMode == InputTarget::DispatchMode::OUTSIDE;
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002690 })) {
2691 LOG(INFO) << "Dropping event because all windows would just receive ACTION_OUTSIDE: "
2692 << entry.getDescription();
2693 outInjectionResult = InputEventInjectionResult::FAILED;
2694 return {};
2695 }
2696
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002697 outInjectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002698
Prabir Pradhan502a7252023-12-01 16:11:24 +00002699 // Now that we have generated all of the input targets for this event, reset the dispatch
2700 // mode for all touched window to AS_IS.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002701 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
Prabir Pradhan502a7252023-12-01 16:11:24 +00002702 touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002703 }
2704
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002705 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou7be50c92023-11-17 17:09:08 -08002706 if (maskedAction == AMOTION_EVENT_ACTION_UP) {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002707 // Pointer went up.
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002708 tempTouchState.removeTouchingPointer(entry.deviceId, entry.pointerProperties[0].id);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002709 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002710 // All pointers up or canceled.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002711 tempTouchState.removeAllPointersForDevice(entry.deviceId);
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002712 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2713 // One pointer went up.
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002714 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
2715 const uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
2716 tempTouchState.removeTouchingPointer(entry.deviceId, pointerId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002717 }
2718
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002719 // Save changes unless the action was scroll in which case the temporary touch
2720 // state was only valid for this one action.
2721 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07002722 if (displayId >= 0) {
Siarhei Vishniakouf372b812023-02-14 18:06:51 -08002723 tempTouchState.clearWindowsWithoutPointers();
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002724 mTouchStatesByDisplay[displayId] = tempTouchState;
2725 } else {
2726 mTouchStatesByDisplay.erase(displayId);
2727 }
2728 }
2729
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08002730 if (tempTouchState.windows.empty()) {
2731 mTouchStatesByDisplay.erase(displayId);
2732 }
2733
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002734 return targets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002735}
2736
arthurhung6d4bed92021-03-17 11:59:33 +08002737void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07002738 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2739 // have an explicit reason to support it.
2740 constexpr bool isStylus = false;
2741
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002742 sp<WindowInfoHandle> dropWindow =
Harry Cutts33476232023-01-30 19:57:29 +00002743 findTouchedWindowAtLocked(displayId, x, y, isStylus, /*ignoreDragWindow=*/true);
arthurhung6d4bed92021-03-17 11:59:33 +08002744 if (dropWindow) {
2745 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002746 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002747 } else {
Arthur Hung54745652022-04-20 07:17:41 +00002748 ALOGW("No window found when drop.");
Prabir Pradhancef936d2021-07-21 16:17:52 +00002749 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002750 }
2751 mDragState.reset();
2752}
2753
2754void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
Arthur Hung3915c1f2022-05-31 07:17:17 +00002755 if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId) {
arthurhungb89ccb02020-12-30 16:19:01 +08002756 return;
2757 }
2758
arthurhung6d4bed92021-03-17 11:59:33 +08002759 if (!mDragState->isStartDrag) {
2760 mDragState->isStartDrag = true;
2761 mDragState->isStylusButtonDownAtStart =
2762 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2763 }
2764
Arthur Hung54745652022-04-20 07:17:41 +00002765 // Find the pointer index by id.
2766 int32_t pointerIndex = 0;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002767 for (; static_cast<uint32_t>(pointerIndex) < entry.getPointerCount(); pointerIndex++) {
Arthur Hung54745652022-04-20 07:17:41 +00002768 const PointerProperties& pointerProperties = entry.pointerProperties[pointerIndex];
2769 if (pointerProperties.id == mDragState->pointerId) {
2770 break;
arthurhung6d4bed92021-03-17 11:59:33 +08002771 }
Arthur Hung54745652022-04-20 07:17:41 +00002772 }
arthurhung6d4bed92021-03-17 11:59:33 +08002773
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002774 if (uint32_t(pointerIndex) == entry.getPointerCount()) {
Arthur Hung54745652022-04-20 07:17:41 +00002775 LOG_ALWAYS_FATAL("Should find a valid pointer index by id %d", mDragState->pointerId);
Arthur Hung54745652022-04-20 07:17:41 +00002776 }
2777
2778 const int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2779 const int32_t x = entry.pointerCoords[pointerIndex].getX();
2780 const int32_t y = entry.pointerCoords[pointerIndex].getY();
2781
2782 switch (maskedAction) {
2783 case AMOTION_EVENT_ACTION_MOVE: {
2784 // Handle the special case : stylus button no longer pressed.
2785 bool isStylusButtonDown =
2786 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2787 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2788 finishDragAndDrop(entry.displayId, x, y);
2789 return;
2790 }
2791
2792 // Prevent stylus interceptor windows from affecting drag and drop behavior for now,
2793 // until we have an explicit reason to support it.
2794 constexpr bool isStylus = false;
2795
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002796 sp<WindowInfoHandle> hoverWindowHandle =
2797 findTouchedWindowAtLocked(entry.displayId, x, y, isStylus,
2798 /*ignoreDragWindow=*/true);
Arthur Hung54745652022-04-20 07:17:41 +00002799 // enqueue drag exit if needed.
2800 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2801 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2802 if (mDragState->dragHoverWindowHandle != nullptr) {
Harry Cutts33476232023-01-30 19:57:29 +00002803 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, /*isExiting=*/true, x,
Arthur Hung54745652022-04-20 07:17:41 +00002804 y);
2805 }
2806 mDragState->dragHoverWindowHandle = hoverWindowHandle;
2807 }
2808 // enqueue drag location if needed.
2809 if (hoverWindowHandle != nullptr) {
Harry Cutts33476232023-01-30 19:57:29 +00002810 enqueueDragEventLocked(hoverWindowHandle, /*isExiting=*/false, x, y);
Arthur Hung54745652022-04-20 07:17:41 +00002811 }
2812 break;
2813 }
2814
2815 case AMOTION_EVENT_ACTION_POINTER_UP:
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002816 if (MotionEvent::getActionIndex(entry.action) != pointerIndex) {
Arthur Hung54745652022-04-20 07:17:41 +00002817 break;
2818 }
2819 // The drag pointer is up.
2820 [[fallthrough]];
2821 case AMOTION_EVENT_ACTION_UP:
2822 finishDragAndDrop(entry.displayId, x, y);
2823 break;
2824 case AMOTION_EVENT_ACTION_CANCEL: {
2825 ALOGD("Receiving cancel when drag and drop.");
2826 sendDropWindowCommandLocked(nullptr, 0, 0);
2827 mDragState.reset();
2828 break;
2829 }
arthurhungb89ccb02020-12-30 16:19:01 +08002830 }
2831}
2832
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002833std::optional<InputTarget> InputDispatcher::createInputTargetLocked(
2834 const sp<android::gui::WindowInfoHandle>& windowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002835 InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002836 std::optional<nsecs_t> firstDownTimeInTarget) const {
2837 std::shared_ptr<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
2838 if (inputChannel == nullptr) {
2839 ALOGW("Not creating InputTarget for %s, no input channel", windowHandle->getName().c_str());
2840 return {};
2841 }
2842 InputTarget inputTarget;
2843 inputTarget.inputChannel = inputChannel;
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00002844 inputTarget.windowHandle = windowHandle;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002845 inputTarget.dispatchMode = dispatchMode;
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002846 inputTarget.flags = targetFlags;
2847 inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor;
2848 inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
2849 const auto& displayInfoIt = mDisplayInfos.find(windowHandle->getInfo()->displayId);
2850 if (displayInfoIt != mDisplayInfos.end()) {
2851 inputTarget.displayTransform = displayInfoIt->second.transform;
2852 } else {
Siarhei Vishniakou580fb3a2023-05-05 15:02:20 -07002853 // DisplayInfo not found for this window on display windowHandle->getInfo()->displayId.
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002854 // TODO(b/198444055): Make this an error message after 'setInputWindows' API is removed.
2855 }
2856 return inputTarget;
2857}
2858
chaviw98318de2021-05-19 16:45:23 -05002859void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002860 InputTarget::DispatchMode dispatchMode,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002861 ftl::Flags<InputTarget::Flags> targetFlags,
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002862 std::optional<nsecs_t> firstDownTimeInTarget,
Siarhei Vishniakouf75cddb2022-10-25 10:42:16 -07002863 std::vector<InputTarget>& inputTargets) const {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002864 std::vector<InputTarget>::iterator it =
2865 std::find_if(inputTargets.begin(), inputTargets.end(),
2866 [&windowHandle](const InputTarget& inputTarget) {
2867 return inputTarget.inputChannel->getConnectionToken() ==
2868 windowHandle->getToken();
2869 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002870
chaviw98318de2021-05-19 16:45:23 -05002871 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002872
2873 if (it == inputTargets.end()) {
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002874 std::optional<InputTarget> target =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002875 createInputTargetLocked(windowHandle, dispatchMode, targetFlags,
2876 firstDownTimeInTarget);
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002877 if (!target) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002878 return;
2879 }
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002880 inputTargets.push_back(*target);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002881 it = inputTargets.end() - 1;
2882 }
2883
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002884 if (it->flags != targetFlags) {
2885 LOG(ERROR) << "Flags don't match! targetFlags=" << targetFlags.string() << ", it=" << *it;
2886 }
2887 if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
2888 LOG(ERROR) << "Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
2889 << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
2890 }
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002891}
2892
2893void InputDispatcher::addPointerWindowTargetLocked(
2894 const sp<android::gui::WindowInfoHandle>& windowHandle,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002895 InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
2896 std::bitset<MAX_POINTER_ID + 1> pointerIds, std::optional<nsecs_t> firstDownTimeInTarget,
2897 std::vector<InputTarget>& inputTargets) const REQUIRES(mLock) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002898 if (pointerIds.none()) {
2899 for (const auto& target : inputTargets) {
2900 LOG(INFO) << "Target: " << target;
2901 }
2902 LOG(FATAL) << "No pointers specified for " << windowHandle->getName();
2903 return;
2904 }
2905 std::vector<InputTarget>::iterator it =
2906 std::find_if(inputTargets.begin(), inputTargets.end(),
2907 [&windowHandle](const InputTarget& inputTarget) {
2908 return inputTarget.inputChannel->getConnectionToken() ==
2909 windowHandle->getToken();
2910 });
2911
2912 // This is a hack, because the actual entry could potentially be an ACTION_DOWN event that
2913 // causes a HOVER_EXIT to be generated. That means that the same entry of ACTION_DOWN would
2914 // have DISPATCH_AS_HOVER_EXIT and DISPATCH_AS_IS. And therefore, we have to create separate
2915 // input targets for hovering pointers and for touching pointers.
2916 // If we picked an existing input target above, but it's for HOVER_EXIT - let's use a new
2917 // target instead.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002918 if (it != inputTargets.end() && it->dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002919 // Force the code below to create a new input target
2920 it = inputTargets.end();
2921 }
2922
2923 const WindowInfo* windowInfo = windowHandle->getInfo();
2924
2925 if (it == inputTargets.end()) {
2926 std::optional<InputTarget> target =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002927 createInputTargetLocked(windowHandle, dispatchMode, targetFlags,
2928 firstDownTimeInTarget);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002929 if (!target) {
2930 return;
2931 }
2932 inputTargets.push_back(*target);
2933 it = inputTargets.end() - 1;
2934 }
2935
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002936 if (it->dispatchMode != dispatchMode) {
2937 LOG(ERROR) << __func__ << ": DispatchMode doesn't match! ignoring new mode="
2938 << ftl::enum_string(dispatchMode) << ", it=" << *it;
2939 }
Siarhei Vishniakou4bd0b7c2023-10-27 00:51:14 -07002940 if (it->flags != targetFlags) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002941 LOG(ERROR) << __func__ << ": Flags don't match! new targetFlags=" << targetFlags.string()
2942 << ", it=" << *it;
Siarhei Vishniakou4bd0b7c2023-10-27 00:51:14 -07002943 }
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002944 if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00002945 LOG(ERROR) << __func__ << ": Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002946 << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
2947 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002948
chaviw1ff3d1e2020-07-01 15:53:47 -07002949 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002950}
2951
Michael Wright3dd60e22019-03-27 22:06:44 +00002952void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002953 int32_t displayId) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002954 auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
2955 if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
Michael Wright3dd60e22019-03-27 22:06:44 +00002956
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002957 for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
2958 InputTarget target;
2959 target.inputChannel = monitor.inputChannel;
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002960 // target.firstDownTimeInTarget is not set for global monitors. It is only required in split
2961 // touch and global monitoring works as intended even without setting firstDownTimeInTarget
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002962 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
2963 target.displayTransform = it->second.transform;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002964 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002965 target.setDefaultPointerTransform(target.displayTransform);
2966 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002967 }
2968}
2969
Robert Carrc9bf1d32020-04-13 17:21:08 -07002970/**
2971 * Indicate whether one window handle should be considered as obscuring
2972 * another window handle. We only check a few preconditions. Actually
2973 * checking the bounds is left to the caller.
2974 */
chaviw98318de2021-05-19 16:45:23 -05002975static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2976 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002977 // Compare by token so cloned layers aren't counted
2978 if (haveSameToken(windowHandle, otherHandle)) {
2979 return false;
2980 }
2981 auto info = windowHandle->getInfo();
2982 auto otherInfo = otherHandle->getInfo();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002983 if (otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002984 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002985 } else if (otherInfo->alpha == 0 &&
2986 otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002987 // Those act as if they were invisible, so we don't need to flag them.
2988 // We do want to potentially flag touchable windows even if they have 0
2989 // opacity, since they can consume touches and alter the effects of the
2990 // user interaction (eg. apps that rely on
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002991 // Flags::WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002992 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2993 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002994 } else if (info->ownerUid == otherInfo->ownerUid) {
2995 // If ownerUid is the same we don't generate occlusion events as there
2996 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002997 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002998 } else if (otherInfo->inputConfig.test(gui::WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002999 return false;
3000 } else if (otherInfo->displayId != info->displayId) {
3001 return false;
3002 }
3003 return true;
3004}
3005
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003006/**
3007 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
3008 * untrusted, one should check:
3009 *
3010 * 1. If result.hasBlockingOcclusion is true.
3011 * If it's, it means the touch should be blocked due to a window with occlusion mode of
3012 * BLOCK_UNTRUSTED.
3013 *
3014 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
3015 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
3016 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
3017 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
3018 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
3019 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
3020 *
3021 * If neither of those is true, then it means the touch can be allowed.
3022 */
3023InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05003024 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
3025 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003026 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05003027 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003028 TouchOcclusionInfo info;
3029 info.hasBlockingOcclusion = false;
3030 info.obscuringOpacity = 0;
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003031 info.obscuringUid = gui::Uid::INVALID;
3032 std::map<gui::Uid, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05003033 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003034 if (windowHandle == otherHandle) {
3035 break; // All future windows are below us. Exit early.
3036 }
chaviw98318de2021-05-19 16:45:23 -05003037 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00003038 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
3039 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003040 if (DEBUG_TOUCH_OCCLUSION) {
3041 info.debugInfo.push_back(
Harry Cutts101ee9b2023-07-06 18:04:14 +00003042 dumpWindowForTouchOcclusion(otherInfo, /*isTouchedWindow=*/false));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003043 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003044 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
3045 // we perform the checks below to see if the touch can be propagated or not based on the
3046 // window's touch occlusion mode
3047 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
3048 info.hasBlockingOcclusion = true;
3049 info.obscuringUid = otherInfo->ownerUid;
3050 info.obscuringPackage = otherInfo->packageName;
3051 break;
3052 }
3053 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003054 const auto uid = otherInfo->ownerUid;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003055 float opacity =
3056 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
3057 // Given windows A and B:
3058 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
3059 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
3060 opacityByUid[uid] = opacity;
3061 if (opacity > info.obscuringOpacity) {
3062 info.obscuringOpacity = opacity;
3063 info.obscuringUid = uid;
3064 info.obscuringPackage = otherInfo->packageName;
3065 }
3066 }
3067 }
3068 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003069 if (DEBUG_TOUCH_OCCLUSION) {
Harry Cutts101ee9b2023-07-06 18:04:14 +00003070 info.debugInfo.push_back(dumpWindowForTouchOcclusion(windowInfo, /*isTouchedWindow=*/true));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003071 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003072 return info;
3073}
3074
chaviw98318de2021-05-19 16:45:23 -05003075std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003076 bool isTouchedWindow) const {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003077 return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
Prabir Pradhan51e7db02022-02-07 06:02:57 -08003078 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
3079 "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
3080 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08003081 isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003082 info->ownerUid.toString().c_str(), info->id,
Chavi Weingarten7f019192023-08-08 20:39:01 +00003083 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frame.left,
3084 info->frame.top, info->frame.right, info->frame.bottom,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003085 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
3086 info->inputConfig.string().c_str(), toString(info->token != nullptr),
3087 info->applicationInfo.name.c_str(),
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07003088 binderToString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003089}
3090
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003091bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
3092 if (occlusionInfo.hasBlockingOcclusion) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003093 ALOGW("Untrusted touch due to occlusion by %s/%s", occlusionInfo.obscuringPackage.c_str(),
3094 occlusionInfo.obscuringUid.toString().c_str());
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003095 return false;
3096 }
3097 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003098 ALOGW("Untrusted touch due to occlusion by %s/%s (obscuring opacity = "
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003099 "%.2f, maximum allowed = %.2f)",
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003100 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid.toString().c_str(),
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003101 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
3102 return false;
3103 }
3104 return true;
3105}
3106
chaviw98318de2021-05-19 16:45:23 -05003107bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003108 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003109 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05003110 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3111 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07003112 if (windowHandle == otherHandle) {
3113 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08003114 }
chaviw98318de2021-05-19 16:45:23 -05003115 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07003116 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08003117 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003118 return true;
3119 }
3120 }
3121 return false;
3122}
3123
chaviw98318de2021-05-19 16:45:23 -05003124bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003125 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05003126 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3127 const WindowInfo* windowInfo = windowHandle->getInfo();
3128 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07003129 if (windowHandle == otherHandle) {
3130 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003131 }
chaviw98318de2021-05-19 16:45:23 -05003132 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07003133 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08003134 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003135 return true;
3136 }
3137 }
3138 return false;
3139}
3140
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003141std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05003142 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003143 if (applicationHandle != nullptr) {
3144 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07003145 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003146 } else {
3147 return applicationHandle->getName();
3148 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003149 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07003150 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003151 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003152 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003153 }
3154}
3155
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003156void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00003157 if (!isUserActivityEvent(eventEntry)) {
3158 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003159 return;
3160 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003161 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05003162 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Josep del Riob3981622023-04-18 15:49:45 +00003163 const WindowInfo* windowDisablingUserActivityInfo = nullptr;
Tiger Huang721e26f2018-07-24 22:26:19 +08003164 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003165 const WindowInfo* info = focusedWindowHandle->getInfo();
Prabir Pradhan51e7db02022-02-07 06:02:57 -08003166 if (info->inputConfig.test(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY)) {
Josep del Riob3981622023-04-18 15:49:45 +00003167 windowDisablingUserActivityInfo = info;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003168 }
3169 }
3170
3171 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003172 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003173 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003174 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3175 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003176 return;
3177 }
Josep del Riob3981622023-04-18 15:49:45 +00003178 if (windowDisablingUserActivityInfo != nullptr) {
3179 if (DEBUG_DISPATCH_CYCLE) {
3180 ALOGD("Not poking user activity: disabled by window '%s'.",
3181 windowDisablingUserActivityInfo->name.c_str());
3182 }
3183 return;
3184 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003185 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003186 eventType = USER_ACTIVITY_EVENT_TOUCH;
3187 }
3188 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003189 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003190 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003191 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3192 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003193 return;
3194 }
Josep del Riob3981622023-04-18 15:49:45 +00003195 // If the key code is unknown, we don't consider it user activity
3196 if (keyEntry.keyCode == AKEYCODE_UNKNOWN) {
3197 return;
3198 }
3199 // Don't inhibit events that were intercepted or are not passed to
3200 // the apps, like system shortcuts
3201 if (windowDisablingUserActivityInfo != nullptr &&
3202 keyEntry.interceptKeyResult != KeyEntry::InterceptKeyResult::SKIP &&
3203 keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER) {
3204 if (DEBUG_DISPATCH_CYCLE) {
3205 ALOGD("Not poking user activity: disabled by window '%s'.",
3206 windowDisablingUserActivityInfo->name.c_str());
3207 }
3208 return;
3209 }
3210
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003211 eventType = USER_ACTIVITY_EVENT_BUTTON;
3212 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003213 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00003214 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003215 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08003216 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003217 break;
3218 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003219 }
3220
Prabir Pradhancef936d2021-07-21 16:17:52 +00003221 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
3222 REQUIRES(mLock) {
3223 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003224 mPolicy.pokeUserActivity(eventTime, eventType, displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00003225 };
3226 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003227}
3228
3229void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003230 const std::shared_ptr<Connection>& connection,
Prabir Pradhan24047542023-11-02 17:14:59 +00003231 std::shared_ptr<const EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003232 const InputTarget& inputTarget) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003233 ATRACE_NAME_IF(ATRACE_ENABLED(),
3234 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
3235 connection->getInputChannelName().c_str(), eventEntry->id));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003236 if (DEBUG_DISPATCH_CYCLE) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003237 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=%s, "
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08003238 "globalScaleFactor=%f, pointerIds=%s %s",
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003239 connection->getInputChannelName().c_str(), inputTarget.flags.string().c_str(),
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08003240 inputTarget.globalScaleFactor, bitsetToString(inputTarget.pointerIds).c_str(),
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003241 inputTarget.getPointerInfoString().c_str());
3242 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003243
3244 // Skip this event if the connection status is not normal.
3245 // We don't want to enqueue additional outbound events if the connection is broken.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003246 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003247 if (DEBUG_DISPATCH_CYCLE) {
3248 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003249 connection->getInputChannelName().c_str(),
3250 ftl::enum_string(connection->status).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003251 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003252 return;
3253 }
3254
3255 // Split a motion event if needed.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003256 if (inputTarget.flags.test(InputTarget::Flags::SPLIT)) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003257 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003258 "Entry type %s should not have Flags::SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08003259 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003260
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003261 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003262 if (inputTarget.pointerIds.count() != originalMotionEntry.getPointerCount()) {
Siarhei Vishniakou16e4fa02023-02-16 17:48:56 -08003263 if (!inputTarget.firstDownTimeInTarget.has_value()) {
3264 logDispatchStateLocked();
3265 LOG(FATAL) << "Splitting motion events requires a down time to be set for the "
3266 "target on connection "
3267 << connection->getInputChannelName() << " for "
3268 << originalMotionEntry.getDescription();
3269 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003270 std::unique_ptr<MotionEntry> splitMotionEntry =
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00003271 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds,
3272 inputTarget.firstDownTimeInTarget.value());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003273 if (!splitMotionEntry) {
3274 return; // split event was dropped
3275 }
Arthur Hungb3307ee2021-10-14 10:57:37 +00003276 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
3277 std::string reason = std::string("reason=pointer cancel on split window");
3278 android_log_event_list(LOGTAG_INPUT_CANCEL)
3279 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3280 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003281 if (DEBUG_FOCUS) {
3282 ALOGD("channel '%s' ~ Split motion event.",
3283 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003284 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003285 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003286 enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection,
3287 std::move(splitMotionEntry),
3288 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003289 return;
3290 }
3291 }
3292
3293 // Not splitting. Enqueue dispatch entries for the event as is.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003294 enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection, eventEntry,
3295 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003296}
3297
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003298void InputDispatcher::enqueueDispatchEntryAndStartDispatchCycleLocked(
3299 nsecs_t currentTime, const std::shared_ptr<Connection>& connection,
3300 std::shared_ptr<const EventEntry> eventEntry, const InputTarget& inputTarget) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003301 ATRACE_NAME_IF(ATRACE_ENABLED(),
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003302 StringPrintf("enqueueDispatchEntryAndStartDispatchCycleLocked(inputChannel=%s, "
3303 "id=0x%" PRIx32 ")",
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003304 connection->getInputChannelName().c_str(), eventEntry->id));
Michael Wright3dd60e22019-03-27 22:06:44 +00003305
hongzuo liu95785e22022-09-06 02:51:35 +00003306 const bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003307
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003308 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003309
3310 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003311 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003312 startDispatchCycleLocked(currentTime, connection);
3313 }
3314}
3315
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003316void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,
Prabir Pradhan24047542023-11-02 17:14:59 +00003317 std::shared_ptr<const EventEntry> eventEntry,
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003318 const InputTarget& inputTarget) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003319 // This is a new event.
3320 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003321 std::unique_ptr<DispatchEntry> dispatchEntry =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003322 createDispatchEntry(inputTarget, eventEntry, inputTarget.flags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003323
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003324 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
3325 // different EventEntry than what was passed in.
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003326 eventEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327 // Apply target flags and update the connection's input state.
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003328 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003329 case EventEntry::Type::KEY: {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003330 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*eventEntry);
3331 if (!connection->inputState.trackKey(keyEntry, keyEntry.flags)) {
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -07003332 LOG(WARNING) << "channel " << connection->getInputChannelName()
3333 << "~ dropping inconsistent event: " << *dispatchEntry;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003334 return; // skip the inconsistent event
3335 }
3336 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003337 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003338
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003339 case EventEntry::Type::MOTION: {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003340 std::shared_ptr<const MotionEntry> resolvedMotion =
3341 std::static_pointer_cast<const MotionEntry>(eventEntry);
3342 {
3343 // Determine the resolved motion entry.
3344 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
3345 int32_t resolvedAction = motionEntry.action;
3346 int32_t resolvedFlags = motionEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003347
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003348 if (inputTarget.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003349 resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003350 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003351 resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003352 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_ENTER) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003353 resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003354 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_EXIT) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003355 resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003356 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_ENTER) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003357 resolvedAction = AMOTION_EVENT_ACTION_DOWN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003358 }
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003359 if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
3360 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3361 motionEntry.displayId)) {
3362 if (DEBUG_DISPATCH_CYCLE) {
3363 LOG(DEBUG) << "channel '" << connection->getInputChannelName().c_str()
3364 << "' ~ enqueueDispatchEntryLocked: filling in missing hover "
3365 "enter event";
3366 }
3367 resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3368 }
3369
3370 if (resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
3371 resolvedFlags |= AMOTION_EVENT_FLAG_CANCELED;
3372 }
3373 if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) {
3374 resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3375 }
3376 if (dispatchEntry->targetFlags.test(
3377 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED)) {
3378 resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3379 }
3380
3381 dispatchEntry->resolvedFlags = resolvedFlags;
3382 if (resolvedAction != motionEntry.action) {
3383 // Generate a new MotionEntry with a new eventId using the resolved action and
3384 // flags.
3385 resolvedMotion =
3386 std::make_shared<MotionEntry>(mIdGenerator.nextId(),
3387 motionEntry.injectionState,
3388 motionEntry.eventTime,
3389 motionEntry.deviceId, motionEntry.source,
3390 motionEntry.displayId,
3391 motionEntry.policyFlags, resolvedAction,
3392 motionEntry.actionButton, resolvedFlags,
3393 motionEntry.metaState,
3394 motionEntry.buttonState,
3395 motionEntry.classification,
3396 motionEntry.edgeFlags,
3397 motionEntry.xPrecision,
3398 motionEntry.yPrecision,
3399 motionEntry.xCursorPosition,
3400 motionEntry.yCursorPosition,
3401 motionEntry.downTime,
3402 motionEntry.pointerProperties,
3403 motionEntry.pointerCoords);
3404 if (ATRACE_ENABLED()) {
3405 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3406 ") to MotionEvent(id=0x%" PRIx32 ").",
3407 motionEntry.id, resolvedMotion->id);
3408 ATRACE_NAME(message.c_str());
3409 }
3410
3411 // Set the resolved motion entry in the DispatchEntry.
3412 dispatchEntry->eventEntry = resolvedMotion;
3413 eventEntry = resolvedMotion;
3414 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003415 }
3416
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003417 // Check if we need to cancel any of the ongoing gestures. We don't support multiple
3418 // devices being active at the same time in the same window, so if a new device is
3419 // active, cancel the gesture from the old device.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003420 std::unique_ptr<EventEntry> cancelEvent =
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003421 connection->inputState.cancelConflictingInputStream(*resolvedMotion);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003422 if (cancelEvent != nullptr) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003423 LOG(INFO) << "Canceling pointers for device " << resolvedMotion->deviceId << " in "
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003424 << connection->getInputChannelName() << " with event "
3425 << cancelEvent->getDescription();
3426 std::unique_ptr<DispatchEntry> cancelDispatchEntry =
3427 createDispatchEntry(inputTarget, std::move(cancelEvent),
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003428 ftl::Flags<InputTarget::Flags>());
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003429
3430 // Send these cancel events to the queue before sending the event from the new
3431 // device.
3432 connection->outboundQueue.emplace_back(std::move(cancelDispatchEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003433 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003434
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003435 if (!connection->inputState.trackMotion(*resolvedMotion,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003436 dispatchEntry->resolvedFlags)) {
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -07003437 LOG(WARNING) << "channel " << connection->getInputChannelName()
3438 << "~ dropping inconsistent event: " << *dispatchEntry;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003439 return; // skip the inconsistent event
3440 }
3441
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003442 if ((resolvedMotion->flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3443 (resolvedMotion->policyFlags & POLICY_FLAG_TRUSTED)) {
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003444 // Skip reporting pointer down outside focus to the policy.
3445 break;
3446 }
3447
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003448 dispatchPointerDownOutsideFocus(resolvedMotion->source, resolvedMotion->action,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003449 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003450
3451 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003452 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003453 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003454 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003455 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3456 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003457 break;
3458 }
Chris Yef59a2f42020-10-16 12:55:26 -07003459 case EventEntry::Type::SENSOR: {
3460 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3461 break;
3462 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003463 case EventEntry::Type::CONFIGURATION_CHANGED:
3464 case EventEntry::Type::DEVICE_RESET: {
3465 LOG_ALWAYS_FATAL("%s events should not go to apps",
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003466 ftl::enum_string(eventEntry->type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003467 break;
3468 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003469 }
3470
3471 // Remember that we are waiting for this dispatch to complete.
3472 if (dispatchEntry->hasForegroundTarget()) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003473 incrementPendingForegroundDispatches(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003474 }
3475
3476 // Enqueue the dispatch entry.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003477 connection->outboundQueue.emplace_back(std::move(dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003478 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003479}
3480
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003481/**
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003482 * This function is for debugging and metrics collection. It has two roles.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003483 *
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003484 * The first role is to log input interaction with windows, which helps determine what the user was
3485 * interacting with. For example, if user is touching launcher, we will see an input_interaction log
3486 * that user started interacting with launcher window, as well as any other window that received
3487 * that gesture, such as the wallpaper or other spy windows. A new input_interaction is only logged
3488 * when the set of tokens that received the event changes. It is not logged again as long as the
3489 * user is interacting with the same windows.
3490 *
3491 * The second role is to track input device activity for metrics collection. For each input event,
3492 * we report the set of UIDs that the input device interacted with to the policy. Unlike for the
3493 * input_interaction logs, the device interaction is reported even when the set of interaction
3494 * tokens do not change.
3495 *
3496 * For these purposes, we do not count ACTION_OUTSIDE, ACTION_UP and ACTION_CANCEL actions as
3497 * interaction. This includes up and cancel events for both keys and motions.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003498 */
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003499void InputDispatcher::processInteractionsLocked(const EventEntry& entry,
3500 const std::vector<InputTarget>& targets) {
3501 int32_t deviceId;
3502 nsecs_t eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003503 // Skip ACTION_UP events, and all events other than keys and motions
3504 if (entry.type == EventEntry::Type::KEY) {
3505 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3506 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3507 return;
3508 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003509 deviceId = keyEntry.deviceId;
3510 eventTime = keyEntry.eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003511 } else if (entry.type == EventEntry::Type::MOTION) {
3512 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3513 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003514 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
3515 MotionEvent::getActionMasked(motionEntry.action) == AMOTION_EVENT_ACTION_POINTER_UP) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003516 return;
3517 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003518 deviceId = motionEntry.deviceId;
3519 eventTime = motionEntry.eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003520 } else {
3521 return; // Not a key or a motion
3522 }
3523
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003524 std::set<gui::Uid> interactionUids;
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003525 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003526 std::vector<std::shared_ptr<Connection>> newConnections;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003527 for (const InputTarget& target : targets) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00003528 if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003529 continue; // Skip windows that receive ACTION_OUTSIDE
3530 }
3531
3532 sp<IBinder> token = target.inputChannel->getConnectionToken();
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003533 std::shared_ptr<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003534 if (connection == nullptr) {
3535 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003536 }
3537 newConnectionTokens.insert(std::move(token));
3538 newConnections.emplace_back(connection);
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003539 if (target.windowHandle) {
3540 interactionUids.emplace(target.windowHandle->getInfo()->ownerUid);
3541 }
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003542 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003543
3544 auto command = [this, deviceId, eventTime, uids = std::move(interactionUids)]()
3545 REQUIRES(mLock) {
3546 scoped_unlock unlock(mLock);
3547 mPolicy.notifyDeviceInteraction(deviceId, eventTime, uids);
3548 };
3549 postCommandLocked(std::move(command));
3550
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003551 if (newConnectionTokens == mInteractionConnectionTokens) {
3552 return; // no change
3553 }
3554 mInteractionConnectionTokens = newConnectionTokens;
3555
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003556 std::string targetList;
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003557 for (const std::shared_ptr<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003558 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003559 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003560 std::string message = "Interaction with: " + targetList;
3561 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003562 message += "<none>";
3563 }
3564 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3565}
3566
chaviwfd6d3512019-03-25 13:23:49 -07003567void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003568 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003569 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003570 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3571 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003572 return;
3573 }
3574
Vishnu Nairc519ff72021-01-21 08:23:08 -08003575 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003576 if (focusedToken == token) {
3577 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003578 return;
3579 }
3580
Prabir Pradhancef936d2021-07-21 16:17:52 +00003581 auto command = [this, token]() REQUIRES(mLock) {
3582 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003583 mPolicy.onPointerDownOutsideFocus(token);
Prabir Pradhancef936d2021-07-21 16:17:52 +00003584 };
3585 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003586}
3587
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003588status_t InputDispatcher::publishMotionEvent(Connection& connection,
3589 DispatchEntry& dispatchEntry) const {
3590 const EventEntry& eventEntry = *(dispatchEntry.eventEntry);
3591 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3592
3593 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003594 const PointerCoords* usingCoords = motionEntry.pointerCoords.data();
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003595
3596 // Set the X and Y offset and X and Y scale depending on the input source.
3597 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003598 !(dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS))) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003599 float globalScaleFactor = dispatchEntry.globalScaleFactor;
3600 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003601 for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003602 scaledCoords[i] = motionEntry.pointerCoords[i];
3603 // Don't apply window scale here since we don't want scale to affect raw
3604 // coordinates. The scale will be sent back to the client and applied
3605 // later when requesting relative coordinates.
Harry Cutts33476232023-01-30 19:57:29 +00003606 scaledCoords[i].scale(globalScaleFactor, /*windowXScale=*/1, /*windowYScale=*/1);
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003607 }
3608 usingCoords = scaledCoords;
3609 }
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003610 } else if (dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS)) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003611 // We don't want the dispatch target to know the coordinates
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003612 for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003613 scaledCoords[i].clear();
3614 }
3615 usingCoords = scaledCoords;
3616 }
3617
3618 std::array<uint8_t, 32> hmac = getSignature(motionEntry, dispatchEntry);
3619
3620 // Publish the motion event.
3621 return connection.inputPublisher
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003622 .publishMotionEvent(dispatchEntry.seq, motionEntry.id, motionEntry.deviceId,
3623 motionEntry.source, motionEntry.displayId, std::move(hmac),
3624 motionEntry.action, motionEntry.actionButton,
3625 dispatchEntry.resolvedFlags, motionEntry.edgeFlags,
3626 motionEntry.metaState, motionEntry.buttonState,
3627 motionEntry.classification, dispatchEntry.transform,
3628 motionEntry.xPrecision, motionEntry.yPrecision,
3629 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
3630 dispatchEntry.rawTransform, motionEntry.downTime,
3631 motionEntry.eventTime, motionEntry.getPointerCount(),
3632 motionEntry.pointerProperties.data(), usingCoords);
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003633}
3634
Michael Wrightd02c5b62014-02-10 15:10:22 -08003635void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003636 const std::shared_ptr<Connection>& connection) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003637 ATRACE_NAME_IF(ATRACE_ENABLED(),
3638 StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
3639 connection->getInputChannelName().c_str()));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003640 if (DEBUG_DISPATCH_CYCLE) {
3641 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3642 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003643
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003644 while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003645 std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003646 dispatchEntry->deliveryTime = currentTime;
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08003647 const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003648 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003649
3650 // Publish the event.
3651 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003652 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3653 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003654 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003655 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3656 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003657 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003658 LOG(INFO) << "Publishing " << *dispatchEntry << " to "
3659 << connection->getInputChannelName();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003660 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003661
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003662 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003663 status = connection->inputPublisher
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003664 .publishKeyEvent(dispatchEntry->seq, keyEntry.id,
3665 keyEntry.deviceId, keyEntry.source,
3666 keyEntry.displayId, std::move(hmac),
3667 keyEntry.action, dispatchEntry->resolvedFlags,
3668 keyEntry.keyCode, keyEntry.scanCode,
3669 keyEntry.metaState, keyEntry.repeatCount,
3670 keyEntry.downTime, keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003671 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003672 }
3673
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003674 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003675 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003676 LOG(INFO) << "Publishing " << *dispatchEntry << " to "
3677 << connection->getInputChannelName();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003678 }
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003679 status = publishMotionEvent(*connection, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003680 break;
3681 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003682
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003683 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003684 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003685 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003686 focusEntry.id,
Antonio Kantek3cfec7b2021-11-05 18:26:17 -07003687 focusEntry.hasFocus);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003688 break;
3689 }
3690
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003691 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3692 const TouchModeEntry& touchModeEntry =
3693 static_cast<const TouchModeEntry&>(eventEntry);
3694 status = connection->inputPublisher
3695 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3696 touchModeEntry.inTouchMode);
3697
3698 break;
3699 }
3700
Prabir Pradhan99987712020-11-10 18:43:05 -08003701 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3702 const auto& captureEntry =
3703 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3704 status = connection->inputPublisher
3705 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003706 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003707 break;
3708 }
3709
arthurhungb89ccb02020-12-30 16:19:01 +08003710 case EventEntry::Type::DRAG: {
3711 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3712 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3713 dragEntry.id, dragEntry.x,
3714 dragEntry.y,
3715 dragEntry.isExiting);
3716 break;
3717 }
3718
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003719 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003720 case EventEntry::Type::DEVICE_RESET:
3721 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003722 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003723 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003724 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003725 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003726 }
3727
3728 // Check the result.
3729 if (status) {
3730 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003731 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003732 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003733 "This is unexpected because the wait queue is empty, so the pipe "
3734 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003735 "event to it, status=%s(%d)",
3736 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3737 status);
Harry Cutts33476232023-01-30 19:57:29 +00003738 abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003739 } else {
3740 // Pipe is full and we are waiting for the app to finish process some events
3741 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003742 if (DEBUG_DISPATCH_CYCLE) {
3743 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3744 "waiting for the application to catch up",
3745 connection->getInputChannelName().c_str());
3746 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003747 }
3748 } else {
3749 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003750 "status=%s(%d)",
3751 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3752 status);
Harry Cutts33476232023-01-30 19:57:29 +00003753 abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003754 }
3755 return;
3756 }
3757
3758 // Re-enqueue the event on the wait queue.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003759 const nsecs_t timeoutTime = dispatchEntry->timeoutTime;
3760 connection->waitQueue.emplace_back(std::move(dispatchEntry));
3761 connection->outboundQueue.erase(connection->outboundQueue.begin());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003762 traceOutboundQueueLength(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003763 if (connection->responsive) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003764 mAnrTracker.insert(timeoutTime, connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003765 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003766 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003767 }
3768}
3769
chaviw09c8d2d2020-08-24 15:48:26 -07003770std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3771 size_t size;
3772 switch (event.type) {
3773 case VerifiedInputEvent::Type::KEY: {
3774 size = sizeof(VerifiedKeyEvent);
3775 break;
3776 }
3777 case VerifiedInputEvent::Type::MOTION: {
3778 size = sizeof(VerifiedMotionEvent);
3779 break;
3780 }
3781 }
3782 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3783 return mHmacKeyManager.sign(start, size);
3784}
3785
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003786const std::array<uint8_t, 32> InputDispatcher::getSignature(
3787 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003788 const int32_t actionMasked = MotionEvent::getActionMasked(motionEntry.action);
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003789 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003790 // Only sign events up and down events as the purely move events
3791 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003792 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003793 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003794
3795 VerifiedMotionEvent verifiedEvent =
3796 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3797 verifiedEvent.actionMasked = actionMasked;
3798 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3799 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003800}
3801
3802const std::array<uint8_t, 32> InputDispatcher::getSignature(
3803 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3804 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3805 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003806 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003807}
3808
Michael Wrightd02c5b62014-02-10 15:10:22 -08003809void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003810 const std::shared_ptr<Connection>& connection,
3811 uint32_t seq, bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003812 if (DEBUG_DISPATCH_CYCLE) {
3813 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3814 connection->getInputChannelName().c_str(), seq, toString(handled));
3815 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003816
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003817 if (connection->status == Connection::Status::BROKEN ||
3818 connection->status == Connection::Status::ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003819 return;
3820 }
3821
3822 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003823 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3824 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3825 };
3826 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003827}
3828
3829void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003830 const std::shared_ptr<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003831 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003832 if (DEBUG_DISPATCH_CYCLE) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003833 LOG(INFO) << "channel '" << connection->getInputChannelName() << "'~ " << __func__
3834 << " - notify=" << toString(notify);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003835 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003836
3837 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003838 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003839 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003840 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003841 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003842
3843 // The connection appears to be unrecoverably broken.
3844 // Ignore already broken or zombie connections.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003845 if (connection->status == Connection::Status::NORMAL) {
3846 connection->status = Connection::Status::BROKEN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003847
3848 if (notify) {
3849 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003850 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3851 connection->getInputChannelName().c_str());
3852
3853 auto command = [this, connection]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003854 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003855 mPolicy.notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Prabir Pradhancef936d2021-07-21 16:17:52 +00003856 };
3857 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003858 }
3859 }
3860}
3861
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003862void InputDispatcher::drainDispatchQueue(std::deque<std::unique_ptr<DispatchEntry>>& queue) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003863 while (!queue.empty()) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003864 releaseDispatchEntry(std::move(queue.front()));
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003865 queue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003866 }
3867}
3868
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003869void InputDispatcher::releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003870 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003871 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003872 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003873}
3874
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003875int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3876 std::scoped_lock _l(mLock);
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003877 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003878 if (connection == nullptr) {
3879 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3880 connectionToken.get(), events);
3881 return 0; // remove the callback
3882 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003883
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003884 bool notify;
3885 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3886 if (!(events & ALOOPER_EVENT_INPUT)) {
3887 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3888 "events=0x%x",
3889 connection->getInputChannelName().c_str(), events);
3890 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003891 }
3892
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003893 nsecs_t currentTime = now();
3894 bool gotOne = false;
3895 status_t status = OK;
3896 for (;;) {
3897 Result<InputPublisher::ConsumerResponse> result =
3898 connection->inputPublisher.receiveConsumerResponse();
3899 if (!result.ok()) {
3900 status = result.error().code();
3901 break;
3902 }
3903
3904 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3905 const InputPublisher::Finished& finish =
3906 std::get<InputPublisher::Finished>(*result);
3907 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3908 finish.consumeTime);
3909 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003910 if (shouldReportMetricsForConnection(*connection)) {
3911 const InputPublisher::Timeline& timeline =
3912 std::get<InputPublisher::Timeline>(*result);
3913 mLatencyTracker
3914 .trackGraphicsLatency(timeline.inputEventId,
3915 connection->inputChannel->getConnectionToken(),
3916 std::move(timeline.graphicsTimeline));
3917 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003918 }
3919 gotOne = true;
3920 }
3921 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003922 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003923 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003924 return 1;
3925 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003926 }
3927
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003928 notify = status != DEAD_OBJECT || !connection->monitor;
3929 if (notify) {
3930 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3931 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3932 status);
3933 }
3934 } else {
3935 // Monitor channels are never explicitly unregistered.
3936 // We do it automatically when the remote endpoint is closed so don't warn about them.
3937 const bool stillHaveWindowHandle =
3938 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3939 notify = !connection->monitor && stillHaveWindowHandle;
3940 if (notify) {
3941 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3942 connection->getInputChannelName().c_str(), events);
3943 }
3944 }
3945
3946 // Remove the channel.
3947 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3948 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003949}
3950
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003951void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003952 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003953 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003954 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003955 }
3956}
3957
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003958void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003959 const CancelationOptions& options) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08003960 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003961 for (const Monitor& monitor : monitors) {
3962 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003963 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003964 }
3965}
3966
Michael Wrightd02c5b62014-02-10 15:10:22 -08003967void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003968 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003969 std::shared_ptr<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003970 if (connection == nullptr) {
3971 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003972 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003973
3974 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003975}
3976
3977void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003978 const std::shared_ptr<Connection>& connection, const CancelationOptions& options) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003979 if (connection->status == Connection::Status::BROKEN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003980 return;
3981 }
3982
3983 nsecs_t currentTime = now();
3984
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003985 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003986 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003987
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003988 if (cancelationEvents.empty()) {
3989 return;
3990 }
Vaibhav Devmurari110ba322023-11-17 10:47:16 +00003991
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003992 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3993 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Siarhei Vishniakou2e3e4432023-02-09 18:34:11 -08003994 "with reality: %s, mode=%s.",
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003995 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
Siarhei Vishniakou2e3e4432023-02-09 18:34:11 -08003996 ftl::enum_string(options.mode).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003997 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003998
Arthur Hungb3307ee2021-10-14 10:57:37 +00003999 std::string reason = std::string("reason=").append(options.reason);
4000 android_log_event_list(LOGTAG_INPUT_CANCEL)
4001 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
4002
hongzuo liu95785e22022-09-06 02:51:35 +00004003 const bool wasEmpty = connection->outboundQueue.empty();
Prabir Pradhan16463382023-10-12 23:03:19 +00004004 // The target to use if we don't find a window associated with the channel.
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004005 const InputTarget fallbackTarget{.inputChannel = connection->inputChannel};
Prabir Pradhan16463382023-10-12 23:03:19 +00004006 const auto& token = connection->inputChannel->getConnectionToken();
hongzuo liu95785e22022-09-06 02:51:35 +00004007
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004008 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004009 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004010 std::vector<InputTarget> targets{};
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004011
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004012 switch (cancelationEventEntry->type) {
4013 case EventEntry::Type::KEY: {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004014 const auto& keyEntry = static_cast<const KeyEntry&>(*cancelationEventEntry);
Prabir Pradhan16463382023-10-12 23:03:19 +00004015 const std::optional<int32_t> targetDisplay = keyEntry.displayId != ADISPLAY_ID_NONE
4016 ? std::make_optional(keyEntry.displayId)
4017 : std::nullopt;
4018 if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004019 addWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
4020 /*targetFlags=*/{}, keyEntry.downTime, targets);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004021 } else {
4022 targets.emplace_back(fallbackTarget);
4023 }
4024 logOutboundKeyDetails("cancel - ", keyEntry);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004025 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004026 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004027 case EventEntry::Type::MOTION: {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004028 const auto& motionEntry = static_cast<const MotionEntry&>(*cancelationEventEntry);
Prabir Pradhan16463382023-10-12 23:03:19 +00004029 const std::optional<int32_t> targetDisplay =
4030 motionEntry.displayId != ADISPLAY_ID_NONE
4031 ? std::make_optional(motionEntry.displayId)
4032 : std::nullopt;
4033 if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004034 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004035 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004036 pointerIndex++) {
4037 pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4038 }
Vaibhav Devmurari110ba322023-11-17 10:47:16 +00004039 if (mDragState && mDragState->dragWindow->getToken() == token &&
4040 pointerIds.test(mDragState->pointerId)) {
4041 LOG(INFO) << __func__
4042 << ": Canceling drag and drop because the pointers for the drag "
4043 "window are being canceled.";
4044 sendDropWindowCommandLocked(nullptr, /*x=*/0, /*y=*/0);
4045 mDragState.reset();
4046 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004047 addPointerWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
4048 ftl::Flags<InputTarget::Flags>(), pointerIds,
4049 motionEntry.downTime, targets);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004050 } else {
4051 targets.emplace_back(fallbackTarget);
4052 const auto it = mDisplayInfos.find(motionEntry.displayId);
4053 if (it != mDisplayInfos.end()) {
4054 targets.back().displayTransform = it->second.transform;
4055 targets.back().setDefaultPointerTransform(it->second.transform);
4056 }
4057 }
4058 logOutboundMotionDetails("cancel - ", motionEntry);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004059 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004060 }
Prabir Pradhan99987712020-11-10 18:43:05 -08004061 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004062 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08004063 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
4064 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08004065 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08004066 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004067 break;
4068 }
4069 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07004070 case EventEntry::Type::DEVICE_RESET:
4071 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004072 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08004073 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004074 break;
4075 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004076 }
4077
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004078 if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004079 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), targets[0]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004080 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004081
hongzuo liu95785e22022-09-06 02:51:35 +00004082 // If the outbound queue was previously empty, start the dispatch cycle going.
4083 if (wasEmpty && !connection->outboundQueue.empty()) {
4084 startDispatchCycleLocked(currentTime, connection);
4085 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004086}
4087
Svet Ganov5d3bc372020-01-26 23:11:07 -08004088void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07004089 const nsecs_t downTime, const std::shared_ptr<Connection>& connection,
Arthur Hungc539dbb2022-12-08 07:45:36 +00004090 ftl::Flags<InputTarget::Flags> targetFlags) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08004091 if (connection->status == Connection::Status::BROKEN) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004092 return;
4093 }
4094
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004095 std::vector<std::unique_ptr<EventEntry>> downEvents =
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004096 connection->inputState.synthesizePointerDownEvents(downTime);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004097
4098 if (downEvents.empty()) {
4099 return;
4100 }
4101
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004102 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004103 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
4104 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004105 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08004106
chaviw98318de2021-05-19 16:45:23 -05004107 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08004108 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Svet Ganov5d3bc372020-01-26 23:11:07 -08004109
hongzuo liu95785e22022-09-06 02:51:35 +00004110 const bool wasEmpty = connection->outboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004111 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004112 std::vector<InputTarget> targets{};
Svet Ganov5d3bc372020-01-26 23:11:07 -08004113 switch (downEventEntry->type) {
4114 case EventEntry::Type::MOTION: {
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004115 const auto& motionEntry = static_cast<const MotionEntry&>(*downEventEntry);
4116 if (windowHandle != nullptr) {
4117 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004118 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004119 pointerIndex++) {
4120 pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4121 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004122 addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::AS_IS,
4123 targetFlags, pointerIds, motionEntry.downTime,
4124 targets);
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004125 } else {
4126 targets.emplace_back(InputTarget{.inputChannel = connection->inputChannel,
4127 .flags = targetFlags});
4128 const auto it = mDisplayInfos.find(motionEntry.displayId);
4129 if (it != mDisplayInfos.end()) {
4130 targets.back().displayTransform = it->second.transform;
4131 targets.back().setDefaultPointerTransform(it->second.transform);
4132 }
4133 }
4134 logOutboundMotionDetails("down - ", motionEntry);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004135 break;
4136 }
4137
4138 case EventEntry::Type::KEY:
4139 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004140 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08004141 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08004142 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07004143 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08004144 case EventEntry::Type::SENSOR:
4145 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004146 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08004147 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08004148 break;
4149 }
4150 }
4151
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004152 if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00004153 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), targets[0]);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004154 }
4155
hongzuo liu95785e22022-09-06 02:51:35 +00004156 // If the outbound queue was previously empty, start the dispatch cycle going.
4157 if (wasEmpty && !connection->outboundQueue.empty()) {
4158 startDispatchCycleLocked(downTime, connection);
4159 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08004160}
4161
Arthur Hungc539dbb2022-12-08 07:45:36 +00004162void InputDispatcher::synthesizeCancelationEventsForWindowLocked(
4163 const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options) {
4164 if (windowHandle != nullptr) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07004165 std::shared_ptr<Connection> wallpaperConnection =
4166 getConnectionLocked(windowHandle->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00004167 if (wallpaperConnection != nullptr) {
4168 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection, options);
4169 }
4170 }
4171}
4172
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004173std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004174 const MotionEntry& originalMotionEntry, std::bitset<MAX_POINTER_ID + 1> pointerIds,
4175 nsecs_t splitDownTime) {
4176 ALOG_ASSERT(pointerIds.any());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004177
4178 uint32_t splitPointerIndexMap[MAX_POINTERS];
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004179 std::vector<PointerProperties> splitPointerProperties;
4180 std::vector<PointerCoords> splitPointerCoords;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004181
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004182 uint32_t originalPointerCount = originalMotionEntry.getPointerCount();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004183 uint32_t splitPointerCount = 0;
4184
4185 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004186 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004187 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004188 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004189 uint32_t pointerId = uint32_t(pointerProperties.id);
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004190 if (pointerIds.test(pointerId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004191 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004192 splitPointerProperties.push_back(pointerProperties);
4193 splitPointerCoords.push_back(originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004194 splitPointerCount += 1;
4195 }
4196 }
4197
4198 if (splitPointerCount != pointerIds.count()) {
4199 // This is bad. We are missing some of the pointers that we expected to deliver.
4200 // Most likely this indicates that we received an ACTION_MOVE events that has
4201 // different pointer ids than we expected based on the previous ACTION_DOWN
4202 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
4203 // in this way.
4204 ALOGW("Dropping split motion event because the pointer count is %d but "
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004205 "we expected there to be %zu pointers. This probably means we received "
Siarhei Vishniakou16e4fa02023-02-16 17:48:56 -08004206 "a broken sequence of pointer ids from the input device: %s",
4207 splitPointerCount, pointerIds.count(), originalMotionEntry.getDescription().c_str());
Yi Kong9b14ac62018-07-17 13:48:38 -07004208 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004209 }
4210
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004211 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004212 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004213 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
4214 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07004215 int32_t originalPointerIndex = MotionEvent::getActionIndex(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004216 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004217 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004218 uint32_t pointerId = uint32_t(pointerProperties.id);
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004219 if (pointerIds.test(pointerId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004220 if (pointerIds.count() == 1) {
4221 // The first/last pointer went down/up.
4222 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004223 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08004224 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
4225 ? AMOTION_EVENT_ACTION_CANCEL
4226 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004227 } else {
4228 // A secondary pointer went down/up.
4229 uint32_t splitPointerIndex = 0;
4230 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
4231 splitPointerIndex += 1;
4232 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004233 action = maskedAction |
4234 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004235 }
4236 } else {
4237 // An unrelated pointer changed.
4238 action = AMOTION_EVENT_ACTION_MOVE;
4239 }
4240 }
4241
Siarhei Vishniakou59e302b2023-06-05 08:04:53 -07004242 if (action == AMOTION_EVENT_ACTION_DOWN && splitDownTime != originalMotionEntry.eventTime) {
4243 logDispatchStateLocked();
4244 LOG_ALWAYS_FATAL("Split motion event has mismatching downTime and eventTime for "
4245 "ACTION_DOWN, motionEntry=%s, splitDownTime=%" PRId64,
4246 originalMotionEntry.getDescription().c_str(), splitDownTime);
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004247 }
4248
Garfield Tanff1f1bb2020-01-28 13:24:04 -08004249 int32_t newId = mIdGenerator.nextId();
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00004250 ATRACE_NAME_IF(ATRACE_ENABLED(),
4251 StringPrintf("Split MotionEvent(id=0x%" PRIx32 ") to MotionEvent(id=0x%" PRIx32
4252 ").",
4253 originalMotionEntry.id, newId));
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004254 std::unique_ptr<MotionEntry> splitMotionEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004255 std::make_unique<MotionEntry>(newId, originalMotionEntry.injectionState,
4256 originalMotionEntry.eventTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004257 originalMotionEntry.deviceId, originalMotionEntry.source,
4258 originalMotionEntry.displayId,
4259 originalMotionEntry.policyFlags, action,
4260 originalMotionEntry.actionButton,
4261 originalMotionEntry.flags, originalMotionEntry.metaState,
4262 originalMotionEntry.buttonState,
4263 originalMotionEntry.classification,
4264 originalMotionEntry.edgeFlags,
4265 originalMotionEntry.xPrecision,
4266 originalMotionEntry.yPrecision,
4267 originalMotionEntry.xCursorPosition,
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004268 originalMotionEntry.yCursorPosition, splitDownTime,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004269 splitPointerProperties, splitPointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004270
4271 return splitMotionEntry;
4272}
4273
Asmita Poddardd9a6cd2023-09-26 15:35:12 +00004274void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
4275 std::scoped_lock _l(mLock);
4276 mLatencyTracker.setInputDevices(args.inputDeviceInfos);
4277}
4278
Prabir Pradhan678438e2023-04-13 19:32:51 +00004279void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004280 if (debugInboundEventDetails()) {
Prabir Pradhan678438e2023-04-13 19:32:51 +00004281 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args.eventTime);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004282 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004283
Antonio Kantekf16f2832021-09-28 04:39:20 +00004284 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004285 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004286 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004287
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004288 std::unique_ptr<ConfigurationChangedEntry> newEntry =
Prabir Pradhan678438e2023-04-13 19:32:51 +00004289 std::make_unique<ConfigurationChangedEntry>(args.id, args.eventTime);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004290 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004291 } // release lock
4292
4293 if (needWake) {
4294 mLooper->wake();
4295 }
4296}
4297
Prabir Pradhan678438e2023-04-13 19:32:51 +00004298void InputDispatcher::notifyKey(const NotifyKeyArgs& args) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004299 ALOGD_IF(debugInboundEventDetails(),
4300 "notifyKey - id=%" PRIx32 ", eventTime=%" PRId64
4301 ", deviceId=%d, source=%s, displayId=%" PRId32
4302 "policyFlags=0x%x, action=%s, flags=0x%x, keyCode=%s, scanCode=0x%x, metaState=0x%x, "
4303 "downTime=%" PRId64,
Prabir Pradhan678438e2023-04-13 19:32:51 +00004304 args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4305 args.displayId, args.policyFlags, KeyEvent::actionToString(args.action), args.flags,
4306 KeyEvent::getLabel(args.keyCode), args.scanCode, args.metaState, args.downTime);
Siarhei Vishniakou6773db62023-04-21 11:30:20 -07004307 Result<void> keyCheck = validateKeyEvent(args.action);
4308 if (!keyCheck.ok()) {
4309 LOG(ERROR) << "invalid key event: " << keyCheck.error();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004310 return;
4311 }
4312
Prabir Pradhan678438e2023-04-13 19:32:51 +00004313 uint32_t policyFlags = args.policyFlags;
4314 int32_t flags = args.flags;
4315 int32_t metaState = args.metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07004316 // InputDispatcher tracks and generates key repeats on behalf of
4317 // whatever notifies it, so repeatCount should always be set to 0
4318 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004319 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
4320 policyFlags |= POLICY_FLAG_VIRTUAL;
4321 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
4322 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004323 if (policyFlags & POLICY_FLAG_FUNCTION) {
4324 metaState |= AMETA_FUNCTION_ON;
4325 }
4326
4327 policyFlags |= POLICY_FLAG_TRUSTED;
4328
Prabir Pradhan678438e2023-04-13 19:32:51 +00004329 int32_t keyCode = args.keyCode;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004330 KeyEvent event;
Prabir Pradhan678438e2023-04-13 19:32:51 +00004331 event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC, args.action,
4332 flags, keyCode, args.scanCode, metaState, repeatCount, args.downTime,
4333 args.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004334
Michael Wright2b3c3302018-03-02 17:19:13 +00004335 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004336 mPolicy.interceptKeyBeforeQueueing(event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004337 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4338 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004339 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004340 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004341
Antonio Kantekf16f2832021-09-28 04:39:20 +00004342 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004343 { // acquire lock
4344 mLock.lock();
4345
4346 if (shouldSendKeyToInputFilterLocked(args)) {
4347 mLock.unlock();
4348
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004349 policyFlags |= POLICY_FLAG_FILTERED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004350 if (!mPolicy.filterInputEvent(event, policyFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004351 return; // event was consumed by the filter
4352 }
4353
4354 mLock.lock();
4355 }
4356
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004357 std::unique_ptr<KeyEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004358 std::make_unique<KeyEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4359 args.deviceId, args.source, args.displayId, policyFlags,
4360 args.action, flags, keyCode, args.scanCode, metaState,
4361 repeatCount, args.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004362
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004363 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004364 mLock.unlock();
4365 } // release lock
4366
4367 if (needWake) {
4368 mLooper->wake();
4369 }
4370}
4371
Prabir Pradhan678438e2023-04-13 19:32:51 +00004372bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs& args) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004373 return mInputFilterEnabled;
4374}
4375
Prabir Pradhan678438e2023-04-13 19:32:51 +00004376void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004377 if (debugInboundEventDetails()) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004378 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=%s, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004379 "displayId=%" PRId32 ", policyFlags=0x%x, "
Siarhei Vishniakou6ebd0692022-10-20 15:05:45 -07004380 "action=%s, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004381 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
4382 "yCursorPosition=%f, downTime=%" PRId64,
Prabir Pradhan678438e2023-04-13 19:32:51 +00004383 args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4384 args.displayId, args.policyFlags, MotionEvent::actionToString(args.action).c_str(),
4385 args.actionButton, args.flags, args.metaState, args.buttonState, args.edgeFlags,
4386 args.xPrecision, args.yPrecision, args.xCursorPosition, args.yCursorPosition,
4387 args.downTime);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004388 for (uint32_t i = 0; i < args.getPointerCount(); i++) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004389 ALOGD(" Pointer %d: id=%d, toolType=%s, x=%f, y=%f, pressure=%f, size=%f, "
4390 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, orientation=%f",
Prabir Pradhan678438e2023-04-13 19:32:51 +00004391 i, args.pointerProperties[i].id,
4392 ftl::enum_string(args.pointerProperties[i].toolType).c_str(),
4393 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
4394 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
4395 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
4396 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
4397 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
4398 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
4399 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
4400 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
4401 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004402 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004403 }
Siarhei Vishniakou4ca97272023-03-01 11:31:35 -08004404
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004405 Result<void> motionCheck =
4406 validateMotionEvent(args.action, args.actionButton, args.getPointerCount(),
4407 args.pointerProperties.data());
Siarhei Vishniakou6773db62023-04-21 11:30:20 -07004408 if (!motionCheck.ok()) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004409 LOG(FATAL) << "Invalid event: " << args.dump() << "; reason: " << motionCheck.error();
Siarhei Vishniakou4ca97272023-03-01 11:31:35 -08004410 return;
4411 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004412
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07004413 if (DEBUG_VERIFY_EVENTS) {
4414 auto [it, _] =
4415 mVerifiersByDisplay.try_emplace(args.displayId,
4416 StringPrintf("display %" PRId32, args.displayId));
4417 Result<void> result =
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -07004418 it->second.processMovement(args.deviceId, args.source, args.action,
4419 args.getPointerCount(), args.pointerProperties.data(),
4420 args.pointerCoords.data(), args.flags);
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07004421 if (!result.ok()) {
4422 LOG(FATAL) << "Bad stream: " << result.error() << " caused by " << args.dump();
4423 }
4424 }
4425
Prabir Pradhan678438e2023-04-13 19:32:51 +00004426 uint32_t policyFlags = args.policyFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004427 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004428
4429 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004430 mPolicy.interceptMotionBeforeQueueing(args.displayId, args.eventTime, policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004431 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4432 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004433 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004434 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004435
Antonio Kantekf16f2832021-09-28 04:39:20 +00004436 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004437 { // acquire lock
4438 mLock.lock();
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004439 if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
4440 // Set the flag anyway if we already have an ongoing gesture. That would allow us to
4441 // complete the processing of the current stroke.
Prabir Pradhan678438e2023-04-13 19:32:51 +00004442 const auto touchStateIt = mTouchStatesByDisplay.find(args.displayId);
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004443 if (touchStateIt != mTouchStatesByDisplay.end()) {
4444 const TouchState& touchState = touchStateIt->second;
Linnan Li907ae732023-09-05 17:14:21 +08004445 if (touchState.hasTouchingPointers(args.deviceId) ||
4446 touchState.hasHoveringPointers(args.deviceId)) {
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004447 policyFlags |= POLICY_FLAG_PASS_TO_USER;
4448 }
4449 }
4450 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004451
4452 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004453 ui::Transform displayTransform;
Prabir Pradhan678438e2023-04-13 19:32:51 +00004454 if (const auto it = mDisplayInfos.find(args.displayId); it != mDisplayInfos.end()) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004455 displayTransform = it->second.transform;
4456 }
4457
Michael Wrightd02c5b62014-02-10 15:10:22 -08004458 mLock.unlock();
4459
4460 MotionEvent event;
Prabir Pradhan678438e2023-04-13 19:32:51 +00004461 event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC,
4462 args.action, args.actionButton, args.flags, args.edgeFlags,
4463 args.metaState, args.buttonState, args.classification,
4464 displayTransform, args.xPrecision, args.yPrecision,
4465 args.xCursorPosition, args.yCursorPosition, displayTransform,
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004466 args.downTime, args.eventTime, args.getPointerCount(),
4467 args.pointerProperties.data(), args.pointerCoords.data());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004468
4469 policyFlags |= POLICY_FLAG_FILTERED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004470 if (!mPolicy.filterInputEvent(event, policyFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004471 return; // event was consumed by the filter
4472 }
4473
4474 mLock.lock();
4475 }
4476
4477 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004478 std::unique_ptr<MotionEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004479 std::make_unique<MotionEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4480 args.deviceId, args.source, args.displayId,
4481 policyFlags, args.action, args.actionButton,
4482 args.flags, args.metaState, args.buttonState,
4483 args.classification, args.edgeFlags, args.xPrecision,
4484 args.yPrecision, args.xCursorPosition,
4485 args.yCursorPosition, args.downTime,
4486 args.pointerProperties, args.pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004487
Prabir Pradhan678438e2023-04-13 19:32:51 +00004488 if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4489 IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004490 !mInputFilterEnabled) {
Prabir Pradhan678438e2023-04-13 19:32:51 +00004491 const bool isDown = args.action == AMOTION_EVENT_ACTION_DOWN;
Asmita Poddardd9a6cd2023-09-26 15:35:12 +00004492 std::set<InputDeviceUsageSource> sources = getUsageSourcesForMotionArgs(args);
4493 mLatencyTracker.trackListener(args.id, isDown, args.eventTime, args.readTime,
4494 args.deviceId, sources);
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004495 }
4496
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004497 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004498 mLock.unlock();
4499 } // release lock
4500
4501 if (needWake) {
4502 mLooper->wake();
4503 }
4504}
4505
Prabir Pradhan678438e2023-04-13 19:32:51 +00004506void InputDispatcher::notifySensor(const NotifySensorArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004507 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004508 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4509 " sensorType=%s",
Prabir Pradhan678438e2023-04-13 19:32:51 +00004510 args.id, args.eventTime, args.deviceId, args.source,
4511 ftl::enum_string(args.sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004512 }
Chris Yef59a2f42020-10-16 12:55:26 -07004513
Antonio Kantekf16f2832021-09-28 04:39:20 +00004514 bool needWake = false;
Chris Yef59a2f42020-10-16 12:55:26 -07004515 { // acquire lock
4516 mLock.lock();
4517
4518 // Just enqueue a new sensor event.
4519 std::unique_ptr<SensorEntry> newEntry =
Prabir Pradhan678438e2023-04-13 19:32:51 +00004520 std::make_unique<SensorEntry>(args.id, args.eventTime, args.deviceId, args.source,
4521 /* policyFlags=*/0, args.hwTimestamp, args.sensorType,
4522 args.accuracy, args.accuracyChanged, args.values);
Chris Yef59a2f42020-10-16 12:55:26 -07004523
4524 needWake = enqueueInboundEventLocked(std::move(newEntry));
4525 mLock.unlock();
4526 } // release lock
4527
4528 if (needWake) {
4529 mLooper->wake();
4530 }
4531}
4532
Prabir Pradhan678438e2023-04-13 19:32:51 +00004533void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004534 if (debugInboundEventDetails()) {
Prabir Pradhan678438e2023-04-13 19:32:51 +00004535 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args.eventTime,
4536 args.deviceId, args.isOn);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004537 }
Prabir Pradhana41d2442023-04-20 21:30:40 +00004538 mPolicy.notifyVibratorState(args.deviceId, args.isOn);
Chris Yefb552902021-02-03 17:18:37 -08004539}
4540
Prabir Pradhan678438e2023-04-13 19:32:51 +00004541bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs& args) {
Jackal Guof9696682018-10-05 12:23:23 +08004542 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004543}
4544
Prabir Pradhan678438e2023-04-13 19:32:51 +00004545void InputDispatcher::notifySwitch(const NotifySwitchArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004546 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004547 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4548 "switchMask=0x%08x",
Prabir Pradhan678438e2023-04-13 19:32:51 +00004549 args.eventTime, args.policyFlags, args.switchValues, args.switchMask);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004550 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004551
Prabir Pradhan678438e2023-04-13 19:32:51 +00004552 uint32_t policyFlags = args.policyFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004553 policyFlags |= POLICY_FLAG_TRUSTED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004554 mPolicy.notifySwitch(args.eventTime, args.switchValues, args.switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004555}
4556
Prabir Pradhan678438e2023-04-13 19:32:51 +00004557void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004558 if (debugInboundEventDetails()) {
Prabir Pradhan678438e2023-04-13 19:32:51 +00004559 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args.eventTime,
4560 args.deviceId);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004561 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004562
Antonio Kantekf16f2832021-09-28 04:39:20 +00004563 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004564 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004565 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004566
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004567 std::unique_ptr<DeviceResetEntry> newEntry =
Prabir Pradhan678438e2023-04-13 19:32:51 +00004568 std::make_unique<DeviceResetEntry>(args.id, args.eventTime, args.deviceId);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004569 needWake = enqueueInboundEventLocked(std::move(newEntry));
Siarhei Vishniakou1160ecd2023-06-28 15:57:47 -07004570
4571 for (auto& [_, verifier] : mVerifiersByDisplay) {
4572 verifier.resetDevice(args.deviceId);
4573 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004574 } // release lock
4575
4576 if (needWake) {
4577 mLooper->wake();
4578 }
4579}
4580
Prabir Pradhan678438e2023-04-13 19:32:51 +00004581void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004582 if (debugInboundEventDetails()) {
Prabir Pradhan678438e2023-04-13 19:32:51 +00004583 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args.eventTime,
4584 args.request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004585 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004586
Antonio Kantekf16f2832021-09-28 04:39:20 +00004587 bool needWake = false;
Prabir Pradhan99987712020-11-10 18:43:05 -08004588 { // acquire lock
4589 std::scoped_lock _l(mLock);
Prabir Pradhan678438e2023-04-13 19:32:51 +00004590 auto entry =
4591 std::make_unique<PointerCaptureChangedEntry>(args.id, args.eventTime, args.request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004592 needWake = enqueueInboundEventLocked(std::move(entry));
4593 } // release lock
4594
4595 if (needWake) {
4596 mLooper->wake();
4597 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004598}
4599
Prabir Pradhan5735a322022-04-11 17:23:34 +00004600InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* event,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00004601 std::optional<gui::Uid> targetUid,
Prabir Pradhan5735a322022-04-11 17:23:34 +00004602 InputEventInjectionSync syncMode,
4603 std::chrono::milliseconds timeout,
4604 uint32_t policyFlags) {
Siarhei Vishniakou6773db62023-04-21 11:30:20 -07004605 Result<void> eventValidation = validateInputEvent(*event);
4606 if (!eventValidation.ok()) {
4607 LOG(INFO) << "Injection failed: invalid event: " << eventValidation.error();
4608 return InputEventInjectionResult::FAILED;
4609 }
4610
Prabir Pradhan65613802023-02-22 23:36:58 +00004611 if (debugInboundEventDetails()) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004612 LOG(INFO) << __func__ << ": targetUid=" << toString(targetUid, &uidString)
4613 << ", syncMode=" << ftl::enum_string(syncMode) << ", timeout=" << timeout.count()
4614 << "ms, policyFlags=0x" << std::hex << policyFlags << std::dec
4615 << ", event=" << *event;
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004616 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004617 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004618
Prabir Pradhan5735a322022-04-11 17:23:34 +00004619 policyFlags |= POLICY_FLAG_INJECTED | POLICY_FLAG_TRUSTED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004620
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004621 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004622 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4623 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4624 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4625 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4626 // from events that originate from actual hardware.
Siarhei Vishniakouf4043212023-09-18 19:33:03 -07004627 DeviceId resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004628 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004629 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004630 }
4631
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004632 const bool isAsync = syncMode == InputEventInjectionSync::NONE;
4633 auto injectionState = std::make_shared<InjectionState>(targetUid, isAsync);
4634
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004635 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004636 switch (event->getType()) {
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004637 case InputEventType::KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004638 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
Siarhei Vishniakou6773db62023-04-21 11:30:20 -07004639 const int32_t action = incomingKey.getAction();
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004640 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004641 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4642 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4643 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004644 int32_t keyCode = incomingKey.getKeyCode();
4645 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004646 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004647 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004648 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4649 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4650 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004651
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004652 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4653 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004654 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004655
4656 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4657 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004658 mPolicy.interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004659 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4660 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4661 std::to_string(t.duration().count()).c_str());
4662 }
4663 }
4664
4665 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004666 std::unique_ptr<KeyEntry> injectedEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004667 std::make_unique<KeyEntry>(incomingKey.getId(), injectionState,
4668 incomingKey.getEventTime(), resolvedDeviceId,
4669 incomingKey.getSource(), incomingKey.getDisplayId(),
4670 policyFlags, action, flags, keyCode,
4671 incomingKey.getScanCode(), metaState,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004672 incomingKey.getRepeatCount(),
4673 incomingKey.getDownTime());
4674 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004675 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004676 }
4677
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004678 case InputEventType::MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004679 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004680 const bool isPointerEvent =
4681 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4682 // If a pointer event has no displayId specified, inject it to the default display.
Linnan Li43654e72024-03-28 11:07:13 +00004683 const int32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004684 ? ADISPLAY_ID_DEFAULT
4685 : event->getDisplayId();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004686 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004687
4688 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004689 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004690 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004691 mPolicy.interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004692 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4693 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4694 std::to_string(t.duration().count()).c_str());
4695 }
4696 }
4697
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004698 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4699 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4700 }
4701
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004702 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004703 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004704 const size_t pointerCount = motionEvent.getPointerCount();
4705 const std::vector<PointerProperties>
4706 pointerProperties(motionEvent.getPointerProperties(),
4707 motionEvent.getPointerProperties() + pointerCount);
4708
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004709 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004710 std::unique_ptr<MotionEntry> injectedEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004711 std::make_unique<MotionEntry>(motionEvent.getId(), injectionState,
4712 *sampleEventTimes, resolvedDeviceId,
4713 motionEvent.getSource(), displayId, policyFlags,
4714 motionEvent.getAction(),
Siarhei Vishniakou6773db62023-04-21 11:30:20 -07004715 motionEvent.getActionButton(), flags,
4716 motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004717 motionEvent.getButtonState(),
4718 motionEvent.getClassification(),
4719 motionEvent.getEdgeFlags(),
4720 motionEvent.getXPrecision(),
4721 motionEvent.getYPrecision(),
4722 motionEvent.getRawXCursorPosition(),
4723 motionEvent.getRawYCursorPosition(),
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004724 motionEvent.getDownTime(), pointerProperties,
4725 std::vector<PointerCoords>(samplePointerCoords,
4726 samplePointerCoords +
4727 pointerCount));
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004728 transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004729 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004730 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004731 sampleEventTimes += 1;
Siarhei Vishniakou6773db62023-04-21 11:30:20 -07004732 samplePointerCoords += motionEvent.getPointerCount();
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004733 std::unique_ptr<MotionEntry> nextInjectedEntry = std::make_unique<
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004734 MotionEntry>(motionEvent.getId(), injectionState, *sampleEventTimes,
4735 resolvedDeviceId, motionEvent.getSource(), displayId,
4736 policyFlags, motionEvent.getAction(),
4737 motionEvent.getActionButton(), flags,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004738 motionEvent.getMetaState(), motionEvent.getButtonState(),
4739 motionEvent.getClassification(), motionEvent.getEdgeFlags(),
4740 motionEvent.getXPrecision(), motionEvent.getYPrecision(),
4741 motionEvent.getRawXCursorPosition(),
4742 motionEvent.getRawYCursorPosition(), motionEvent.getDownTime(),
4743 pointerProperties,
4744 std::vector<PointerCoords>(samplePointerCoords,
4745 samplePointerCoords +
4746 pointerCount));
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004747 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
4748 motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004749 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004750 }
4751 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004752 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004753
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004754 default:
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004755 LOG(WARNING) << "Cannot inject " << ftl::enum_string(event->getType()) << " events";
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004756 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004757 }
4758
Michael Wrightd02c5b62014-02-10 15:10:22 -08004759 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004760 while (!injectedEntries.empty()) {
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08004761 if (DEBUG_INJECTION) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004762 LOG(INFO) << "Injecting " << injectedEntries.front()->getDescription();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08004763 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004764 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004765 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004766 }
4767
4768 mLock.unlock();
4769
4770 if (needWake) {
4771 mLooper->wake();
4772 }
4773
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004774 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004775 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004776 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004777
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004778 if (syncMode == InputEventInjectionSync::NONE) {
4779 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004780 } else {
4781 for (;;) {
4782 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004783 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004784 break;
4785 }
4786
4787 nsecs_t remainingTimeout = endTime - now();
4788 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004789 if (DEBUG_INJECTION) {
4790 ALOGD("injectInputEvent - Timed out waiting for injection result "
4791 "to become available.");
4792 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004793 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004794 break;
4795 }
4796
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004797 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004798 }
4799
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004800 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4801 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004802 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004803 if (DEBUG_INJECTION) {
4804 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4805 injectionState->pendingForegroundDispatches);
4806 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004807 nsecs_t remainingTimeout = endTime - now();
4808 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004809 if (DEBUG_INJECTION) {
4810 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4811 "dispatches to finish.");
4812 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004813 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004814 break;
4815 }
4816
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004817 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004818 }
4819 }
4820 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004821 } // release lock
4822
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004823 if (DEBUG_INJECTION) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004824 LOG(INFO) << "injectInputEvent - Finished with result "
4825 << ftl::enum_string(injectionResult);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004826 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004827
4828 return injectionResult;
4829}
4830
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004831std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004832 std::array<uint8_t, 32> calculatedHmac;
4833 std::unique_ptr<VerifiedInputEvent> result;
4834 switch (event.getType()) {
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004835 case InputEventType::KEY: {
Gang Wange9087892020-01-07 12:17:14 -05004836 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4837 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4838 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004839 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004840 break;
4841 }
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004842 case InputEventType::MOTION: {
Gang Wange9087892020-01-07 12:17:14 -05004843 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4844 VerifiedMotionEvent verifiedMotionEvent =
4845 verifiedMotionEventFromMotionEvent(motionEvent);
4846 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004847 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004848 break;
4849 }
4850 default: {
4851 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4852 return nullptr;
4853 }
4854 }
4855 if (calculatedHmac == INVALID_HMAC) {
4856 return nullptr;
4857 }
tyiu1573a672023-02-21 22:38:32 +00004858 if (0 != CRYPTO_memcmp(calculatedHmac.data(), event.getHmac().data(), calculatedHmac.size())) {
Gang Wange9087892020-01-07 12:17:14 -05004859 return nullptr;
4860 }
4861 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004862}
4863
Prabir Pradhan24047542023-11-02 17:14:59 +00004864void InputDispatcher::setInjectionResult(const EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004865 InputEventInjectionResult injectionResult) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004866 if (!entry.injectionState) {
4867 // Not an injected event.
4868 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004869 }
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004870
4871 InjectionState& injectionState = *entry.injectionState;
4872 if (DEBUG_INJECTION) {
4873 LOG(INFO) << "Setting input event injection result to "
4874 << ftl::enum_string(injectionResult);
4875 }
4876
4877 if (injectionState.injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
4878 // Log the outcome since the injector did not wait for the injection result.
4879 switch (injectionResult) {
4880 case InputEventInjectionResult::SUCCEEDED:
4881 ALOGV("Asynchronous input event injection succeeded.");
4882 break;
4883 case InputEventInjectionResult::TARGET_MISMATCH:
4884 ALOGV("Asynchronous input event injection target mismatch.");
4885 break;
4886 case InputEventInjectionResult::FAILED:
4887 ALOGW("Asynchronous input event injection failed.");
4888 break;
4889 case InputEventInjectionResult::TIMED_OUT:
4890 ALOGW("Asynchronous input event injection timed out.");
4891 break;
4892 case InputEventInjectionResult::PENDING:
4893 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4894 break;
4895 }
4896 }
4897
4898 injectionState.injectionResult = injectionResult;
4899 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004900}
4901
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004902void InputDispatcher::transformMotionEntryForInjectionLocked(
4903 MotionEntry& entry, const ui::Transform& injectedTransform) const {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004904 // Input injection works in the logical display coordinate space, but the input pipeline works
4905 // display space, so we need to transform the injected events accordingly.
4906 const auto it = mDisplayInfos.find(entry.displayId);
4907 if (it == mDisplayInfos.end()) return;
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004908 const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004909
Prabir Pradhand9a2ebe2022-07-20 19:25:13 +00004910 if (entry.xCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
4911 entry.yCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
4912 const vec2 cursor =
4913 MotionEvent::calculateTransformedXY(entry.source, transformToDisplay,
4914 {entry.xCursorPosition, entry.yCursorPosition});
4915 entry.xCursorPosition = cursor.x;
4916 entry.yCursorPosition = cursor.y;
4917 }
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004918 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
Prabir Pradhan8e6ce222022-02-24 09:08:54 -08004919 entry.pointerCoords[i] =
4920 MotionEvent::calculateTransformedCoords(entry.source, transformToDisplay,
4921 entry.pointerCoords[i]);
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004922 }
4923}
4924
Prabir Pradhan24047542023-11-02 17:14:59 +00004925void InputDispatcher::incrementPendingForegroundDispatches(const EventEntry& entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004926 if (entry.injectionState) {
4927 entry.injectionState->pendingForegroundDispatches += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004928 }
4929}
4930
Prabir Pradhan24047542023-11-02 17:14:59 +00004931void InputDispatcher::decrementPendingForegroundDispatches(const EventEntry& entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004932 if (entry.injectionState) {
4933 entry.injectionState->pendingForegroundDispatches -= 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004934
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004935 if (entry.injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004936 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004937 }
4938 }
4939}
4940
chaviw98318de2021-05-19 16:45:23 -05004941const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004942 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004943 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004944 auto it = mWindowHandlesByDisplay.find(displayId);
4945 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004946}
4947
chaviw98318de2021-05-19 16:45:23 -05004948sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
Prabir Pradhan16463382023-10-12 23:03:19 +00004949 const sp<IBinder>& windowHandleToken, std::optional<int32_t> displayId) const {
arthurhungbe737672020-06-24 12:29:21 +08004950 if (windowHandleToken == nullptr) {
4951 return nullptr;
4952 }
4953
Prabir Pradhan16463382023-10-12 23:03:19 +00004954 if (!displayId) {
4955 // Look through all displays.
4956 for (auto& it : mWindowHandlesByDisplay) {
4957 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4958 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
4959 if (windowHandle->getToken() == windowHandleToken) {
4960 return windowHandle;
4961 }
Arthur Hungb92218b2018-08-14 12:00:21 +08004962 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004963 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07004964 return nullptr;
4965 }
4966
Prabir Pradhan16463382023-10-12 23:03:19 +00004967 // Only look through the requested display.
4968 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(*displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004969 if (windowHandle->getToken() == windowHandleToken) {
4970 return windowHandle;
4971 }
4972 }
4973 return nullptr;
4974}
4975
chaviw98318de2021-05-19 16:45:23 -05004976sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4977 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004978 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004979 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4980 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004981 if (handle->getId() == windowHandle->getId() &&
4982 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004983 if (windowHandle->getInfo()->displayId != it.first) {
4984 ALOGE("Found window %s in display %" PRId32
4985 ", but it should belong to display %" PRId32,
4986 windowHandle->getName().c_str(), it.first,
4987 windowHandle->getInfo()->displayId);
4988 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004989 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004990 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004991 }
4992 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004993 return nullptr;
4994}
4995
chaviw98318de2021-05-19 16:45:23 -05004996sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004997 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4998 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004999}
5000
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00005001ui::Transform InputDispatcher::getTransformLocked(int32_t displayId) const {
5002 auto displayInfoIt = mDisplayInfos.find(displayId);
5003 return displayInfoIt != mDisplayInfos.end() ? displayInfoIt->second.transform
5004 : kIdentityTransform;
5005}
5006
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005007bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& window,
5008 const MotionEntry& motionEntry) const {
5009 const WindowInfo& info = *window->getInfo();
5010
5011 // Skip spy window targets that are not valid for targeted injection.
5012 if (const auto err = verifyTargetedInjection(window, motionEntry); err) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005013 return false;
5014 }
5015
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005016 if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
5017 ALOGI("Not sending touch event to %s because it is paused", window->getName().c_str());
5018 return false;
5019 }
5020
5021 if (info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL)) {
5022 ALOGW("Not sending touch gesture to %s because it has config NO_INPUT_CHANNEL",
5023 window->getName().c_str());
5024 return false;
5025 }
5026
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005027 std::shared_ptr<Connection> connection = getConnectionLocked(window->getToken());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005028 if (connection == nullptr) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005029 ALOGW("Not sending touch to %s because there's no corresponding connection",
5030 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005031 return false;
5032 }
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005033
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005034 if (!connection->responsive) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005035 ALOGW("Not sending touch to %s because it is not responsive", window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005036 return false;
5037 }
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005038
5039 // Drop events that can't be trusted due to occlusion
5040 const auto [x, y] = resolveTouchedPosition(motionEntry);
5041 TouchOcclusionInfo occlusionInfo = computeTouchOcclusionInfoLocked(window, x, y);
5042 if (!isTouchTrustedLocked(occlusionInfo)) {
5043 if (DEBUG_TOUCH_OCCLUSION) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00005044 ALOGD("Stack of obscuring windows during untrusted touch (%.1f, %.1f):", x, y);
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005045 for (const auto& log : occlusionInfo.debugInfo) {
5046 ALOGD("%s", log.c_str());
5047 }
5048 }
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00005049 ALOGW("Dropping untrusted touch event due to %s/%s", occlusionInfo.obscuringPackage.c_str(),
5050 occlusionInfo.obscuringUid.toString().c_str());
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005051 return false;
5052 }
5053
5054 // Drop touch events if requested by input feature
5055 if (shouldDropInput(motionEntry, window)) {
5056 return false;
5057 }
5058
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005059 return true;
5060}
5061
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005062std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
5063 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005064 auto connectionIt = mConnectionsByToken.find(token);
5065 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07005066 return nullptr;
5067 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005068 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07005069}
5070
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005071void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05005072 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
5073 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005074 // Remove all handles on a display if there are no windows left.
5075 mWindowHandlesByDisplay.erase(displayId);
5076 return;
5077 }
5078
5079 // Since we compare the pointer of input window handles across window updates, we need
5080 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05005081 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
5082 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
5083 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07005084 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005085 }
5086
chaviw98318de2021-05-19 16:45:23 -05005087 std::vector<sp<WindowInfoHandle>> newHandles;
5088 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05005089 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005090 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005091 const bool noInputChannel =
Prabir Pradhan51e7db02022-02-07 06:02:57 -08005092 info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005093 const bool canReceiveInput =
5094 !info->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) ||
5095 !info->inputConfig.test(WindowInfo::InputConfig::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005096 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07005097 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005098 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07005099 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005100 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005101 }
5102
5103 if (info->displayId != displayId) {
5104 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
5105 handle->getName().c_str(), displayId, info->displayId);
5106 continue;
5107 }
5108
Robert Carredd13602020-04-13 17:24:34 -07005109 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
5110 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05005111 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005112 oldHandle->updateFrom(handle);
5113 newHandles.push_back(oldHandle);
5114 } else {
5115 newHandles.push_back(handle);
5116 }
5117 }
5118
5119 // Insert or replace
5120 mWindowHandlesByDisplay[displayId] = newHandles;
5121}
5122
Arthur Hungb92218b2018-08-14 12:00:21 +08005123/**
5124 * Called from InputManagerService, update window handle list by displayId that can receive input.
5125 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
5126 * If set an empty list, remove all handles from the specific display.
5127 * For focused handle, check if need to change and send a cancel event to previous one.
5128 * For removed handle, check if need to send a cancel event if already in touch.
5129 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00005130void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05005131 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005132 if (DEBUG_FOCUS) {
5133 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05005134 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005135 windowList += iwh->getName() + " ";
5136 }
Siarhei Vishniakou366fb5b2023-12-06 11:23:41 -08005137 LOG(INFO) << "setInputWindows displayId=" << displayId << " " << windowList;
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005138 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005139
Prabir Pradhand65552b2021-10-07 11:23:50 -07005140 // Check preconditions for new input windows
chaviw98318de2021-05-19 16:45:23 -05005141 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07005142 const WindowInfo& info = *window->getInfo();
5143
5144 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
Prabir Pradhan51e7db02022-02-07 06:02:57 -08005145 const bool noInputWindow = info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005146 if (noInputWindow && window->getToken() != nullptr) {
5147 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
5148 window->getName().c_str());
5149 window->releaseChannel();
5150 }
Prabir Pradhand65552b2021-10-07 11:23:50 -07005151
Prabir Pradhan5c85e052021-12-22 02:27:12 -08005152 // Ensure all spy windows are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005153 LOG_ALWAYS_FATAL_IF(info.isSpy() &&
5154 !info.inputConfig.test(
5155 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhan5c85e052021-12-22 02:27:12 -08005156 "%s has feature SPY, but is not a trusted overlay.",
5157 window->getName().c_str());
5158
Prabir Pradhand65552b2021-10-07 11:23:50 -07005159 // Ensure all stylus interceptors are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005160 LOG_ALWAYS_FATAL_IF(info.interceptsStylus() &&
5161 !info.inputConfig.test(
5162 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhand65552b2021-10-07 11:23:50 -07005163 "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
5164 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005165 }
5166
Arthur Hung72d8dc32020-03-28 00:48:39 +00005167 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05005168 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005169
chaviw98318de2021-05-19 16:45:23 -05005170 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005171
chaviw98318de2021-05-19 16:45:23 -05005172 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00005173
Vishnu Nairc519ff72021-01-21 08:23:08 -08005174 std::optional<FocusResolver::FocusChanges> changes =
5175 mFocusResolver.setInputWindows(displayId, windowHandles);
5176 if (changes) {
5177 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00005178 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005179
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005180 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5181 mTouchStatesByDisplay.find(displayId);
5182 if (stateIt != mTouchStatesByDisplay.end()) {
5183 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00005184 for (size_t i = 0; i < state.windows.size();) {
5185 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005186 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07005187 LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName()
5188 << " in display %" << displayId;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005189 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00005190 getInputChannelLocked(touchedWindow.windowHandle->getToken());
5191 if (touchedInputChannel != nullptr) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00005192 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Arthur Hung72d8dc32020-03-28 00:48:39 +00005193 "touched window was removed");
5194 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005195 // Since we are about to drop the touch, cancel the events for the wallpaper as
5196 // well.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005197 if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005198 touchedWindow.windowHandle->getInfo()->inputConfig.test(
5199 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005200 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
Arthur Hungc539dbb2022-12-08 07:45:36 +00005201 synthesizeCancelationEventsForWindowLocked(wallpaper, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005202 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005203 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005204 state.windows.erase(state.windows.begin() + i);
5205 } else {
5206 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005207 }
5208 }
arthurhungb89ccb02020-12-30 16:19:01 +08005209
arthurhung6d4bed92021-03-17 11:59:33 +08005210 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08005211 // could just clear the state here.
Arthur Hung3915c1f2022-05-31 07:17:17 +00005212 if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId &&
arthurhung6d4bed92021-03-17 11:59:33 +08005213 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08005214 windowHandles.end()) {
Arthur Hung3915c1f2022-05-31 07:17:17 +00005215 ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str());
5216 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08005217 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08005218 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005219 }
Arthur Hung25e2af12020-03-26 12:58:37 +00005220
Arthur Hung72d8dc32020-03-28 00:48:39 +00005221 // Release information for windows that are no longer present.
5222 // This ensures that unused input channels are released promptly.
5223 // Otherwise, they might stick around until the window handle is destroyed
5224 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05005225 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005226 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00005227 if (DEBUG_FOCUS) {
5228 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00005229 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005230 oldWindowHandle->releaseChannel();
Arthur Hung25e2af12020-03-26 12:58:37 +00005231 }
chaviw291d88a2019-02-14 10:33:58 -08005232 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005233}
5234
5235void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07005236 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005237 if (DEBUG_FOCUS) {
5238 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
5239 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
5240 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005241 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005242 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07005243 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005244 } // release lock
5245
5246 // Wake up poll loop since it may need to make new input dispatching choices.
5247 mLooper->wake();
5248}
5249
Vishnu Nair599f1412021-06-21 10:39:58 -07005250void InputDispatcher::setFocusedApplicationLocked(
5251 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
5252 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
5253 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
5254
5255 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
5256 return; // This application is already focused. No need to wake up or change anything.
5257 }
5258
5259 // Set the new application handle.
5260 if (inputApplicationHandle != nullptr) {
5261 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
5262 } else {
5263 mFocusedApplicationHandlesByDisplay.erase(displayId);
5264 }
5265
5266 // No matter what the old focused application was, stop waiting on it because it is
5267 // no longer focused.
5268 resetNoFocusedWindowTimeoutLocked();
5269}
5270
Tiger Huang721e26f2018-07-24 22:26:19 +08005271/**
5272 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
5273 * the display not specified.
5274 *
5275 * We track any unreleased events for each window. If a window loses the ability to receive the
5276 * released event, we will send a cancel event to it. So when the focused display is changed, we
5277 * cancel all the unreleased display-unspecified events for the focused window on the old focused
5278 * display. The display-specified events won't be affected.
5279 */
5280void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005281 if (DEBUG_FOCUS) {
5282 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
5283 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005284 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005285 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08005286
5287 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005288 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08005289 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005290 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005291 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07005292 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08005293 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005294 CancelationOptions
Michael Wrightfb04fd52022-11-24 22:31:11 +00005295 options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005296 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005297 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08005298 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
5299 }
5300 }
5301 mFocusedDisplayId = displayId;
5302
Chris Ye3c2d6f52020-08-09 10:39:48 -07005303 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08005304 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00005305 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08005306
Vishnu Nairad321cd2020-08-20 16:40:21 -07005307 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08005308 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005309 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005310 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08005311 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08005312 }
5313 }
5314 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005315 } // release lock
5316
5317 // Wake up poll loop since it may need to make new input dispatching choices.
5318 mLooper->wake();
5319}
5320
Michael Wrightd02c5b62014-02-10 15:10:22 -08005321void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005322 if (DEBUG_FOCUS) {
5323 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
5324 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005325
5326 bool changed;
5327 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005328 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005329
5330 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
5331 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005332 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005333 }
5334
5335 if (mDispatchEnabled && !enabled) {
5336 resetAndDropEverythingLocked("dispatcher is being disabled");
5337 }
5338
5339 mDispatchEnabled = enabled;
5340 mDispatchFrozen = frozen;
5341 changed = true;
5342 } else {
5343 changed = false;
5344 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005345 } // release lock
5346
5347 if (changed) {
5348 // Wake up poll loop since it may need to make new input dispatching choices.
5349 mLooper->wake();
5350 }
5351}
5352
5353void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005354 if (DEBUG_FOCUS) {
5355 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
5356 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005357
5358 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005359 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005360
5361 if (mInputFilterEnabled == enabled) {
5362 return;
5363 }
5364
5365 mInputFilterEnabled = enabled;
5366 resetAndDropEverythingLocked("input filter is being enabled or disabled");
5367 } // release lock
5368
5369 // Wake up poll loop since there might be work to do to drop everything.
5370 mLooper->wake();
5371}
5372
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00005373bool InputDispatcher::setInTouchMode(bool inTouchMode, gui::Pid pid, gui::Uid uid,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00005374 bool hasPermission, int32_t displayId) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00005375 bool needWake = false;
5376 {
5377 std::scoped_lock lock(mLock);
Antonio Kantek15beb512022-06-13 22:35:41 +00005378 ALOGD_IF(DEBUG_TOUCH_MODE,
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00005379 "Request to change touch mode to %s (calling pid=%s, uid=%s, "
Antonio Kantek15beb512022-06-13 22:35:41 +00005380 "hasPermission=%s, target displayId=%d, mTouchModePerDisplay[displayId]=%s)",
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00005381 toString(inTouchMode), pid.toString().c_str(), uid.toString().c_str(),
5382 toString(hasPermission), displayId,
Antonio Kantek15beb512022-06-13 22:35:41 +00005383 mTouchModePerDisplay.count(displayId) == 0
5384 ? "not set"
5385 : std::to_string(mTouchModePerDisplay[displayId]).c_str());
5386
Antonio Kantek15beb512022-06-13 22:35:41 +00005387 auto touchModeIt = mTouchModePerDisplay.find(displayId);
5388 if (touchModeIt != mTouchModePerDisplay.end() && touchModeIt->second == inTouchMode) {
Antonio Kantekea47acb2021-12-23 12:41:25 -08005389 return false;
Antonio Kantekf16f2832021-09-28 04:39:20 +00005390 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005391 if (!hasPermission) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005392 if (!focusedWindowIsOwnedByLocked(pid, uid) &&
5393 !recentWindowsAreOwnedByLocked(pid, uid)) {
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00005394 ALOGD("Touch mode switch rejected, caller (pid=%s, uid=%s) doesn't own the focused "
Antonio Kantek48710e42022-03-24 14:19:30 -07005395 "window nor none of the previously interacted window",
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00005396 pid.toString().c_str(), uid.toString().c_str());
Antonio Kantekea47acb2021-12-23 12:41:25 -08005397 return false;
5398 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00005399 }
Antonio Kantek15beb512022-06-13 22:35:41 +00005400 mTouchModePerDisplay[displayId] = inTouchMode;
5401 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode,
5402 displayId);
Antonio Kantekf16f2832021-09-28 04:39:20 +00005403 needWake = enqueueInboundEventLocked(std::move(entry));
5404 } // release lock
5405
5406 if (needWake) {
5407 mLooper->wake();
5408 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005409 return true;
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08005410}
5411
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00005412bool InputDispatcher::focusedWindowIsOwnedByLocked(gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005413 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
5414 if (focusedToken == nullptr) {
5415 return false;
5416 }
5417 sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken);
5418 return isWindowOwnedBy(windowHandle, pid, uid);
5419}
5420
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00005421bool InputDispatcher::recentWindowsAreOwnedByLocked(gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005422 return std::find_if(mInteractionConnectionTokens.begin(), mInteractionConnectionTokens.end(),
5423 [&](const sp<IBinder>& connectionToken) REQUIRES(mLock) {
5424 const sp<WindowInfoHandle> windowHandle =
5425 getWindowHandleLocked(connectionToken);
5426 return isWindowOwnedBy(windowHandle, pid, uid);
5427 }) != mInteractionConnectionTokens.end();
5428}
5429
Bernardo Rufinoea97d182020-08-19 14:43:14 +01005430void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
5431 if (opacity < 0 || opacity > 1) {
5432 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
5433 return;
5434 }
5435
5436 std::scoped_lock lock(mLock);
5437 mMaximumObscuringOpacityForTouch = opacity;
5438}
5439
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005440std::tuple<TouchState*, TouchedWindow*, int32_t /*displayId*/>
5441InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) {
Arthur Hungabbb9d82021-09-01 14:52:30 +00005442 for (auto& [displayId, state] : mTouchStatesByDisplay) {
5443 for (TouchedWindow& w : state.windows) {
5444 if (w.windowHandle->getToken() == token) {
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005445 return std::make_tuple(&state, &w, displayId);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005446 }
5447 }
5448 }
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005449 return std::make_tuple(nullptr, nullptr, ADISPLAY_ID_DEFAULT);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005450}
5451
arthurhungb89ccb02020-12-30 16:19:01 +08005452bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5453 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08005454 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005455 if (DEBUG_FOCUS) {
5456 ALOGD("Trivial transfer to same window.");
5457 }
chaviwfbe5d9c2018-12-26 12:23:37 -08005458 return true;
5459 }
5460
Michael Wrightd02c5b62014-02-10 15:10:22 -08005461 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005462 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005463
Arthur Hungabbb9d82021-09-01 14:52:30 +00005464 // Find the target touch state and touched window by fromToken.
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005465 auto [state, touchedWindow, displayId] = findTouchStateWindowAndDisplayLocked(fromToken);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005466
Arthur Hungabbb9d82021-09-01 14:52:30 +00005467 if (state == nullptr || touchedWindow == nullptr) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005468 ALOGD("Touch transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005469 return false;
5470 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005471 std::set<int32_t> deviceIds = touchedWindow->getTouchingDeviceIds();
5472 if (deviceIds.size() != 1) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07005473 LOG(INFO) << "Can't transfer touch. Currently touching devices: " << dumpSet(deviceIds)
5474 << " for window: " << touchedWindow->dump();
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005475 return false;
5476 }
5477 const int32_t deviceId = *deviceIds.begin();
Arthur Hungabbb9d82021-09-01 14:52:30 +00005478
Arthur Hungabbb9d82021-09-01 14:52:30 +00005479 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
5480 if (toWindowHandle == nullptr) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005481 ALOGW("Cannot transfer touch because to window not found.");
Arthur Hungabbb9d82021-09-01 14:52:30 +00005482 return false;
5483 }
5484
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005485 if (DEBUG_FOCUS) {
5486 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00005487 touchedWindow->windowHandle->getName().c_str(),
5488 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005489 }
5490
Arthur Hungabbb9d82021-09-01 14:52:30 +00005491 // Erase old window.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005492 ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags;
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005493 std::bitset<MAX_POINTER_ID + 1> pointerIds = touchedWindow->getTouchingPointers(deviceId);
Arthur Hungc539dbb2022-12-08 07:45:36 +00005494 sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
Arthur Hungabbb9d82021-09-01 14:52:30 +00005495 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005496
Arthur Hungabbb9d82021-09-01 14:52:30 +00005497 // Add new window.
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00005498 nsecs_t downTimeInTarget = now();
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005499 ftl::Flags<InputTarget::Flags> newTargetFlags =
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00005500 oldTargetFlags & (InputTarget::Flags::SPLIT);
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005501 if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005502 newTargetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005503 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00005504 state->addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags,
5505 deviceId, pointerIds, downTimeInTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005506
Arthur Hungabbb9d82021-09-01 14:52:30 +00005507 // Store the dragging window.
5508 if (isDragDrop) {
Arthur Hungb75c2aa2022-07-15 09:35:36 +00005509 if (pointerIds.count() != 1) {
5510 ALOGW("The drag and drop cannot be started when there is no pointer or more than 1"
5511 " pointer on the window.");
Arthur Hung54745652022-04-20 07:17:41 +00005512 return false;
5513 }
Arthur Hungb75c2aa2022-07-15 09:35:36 +00005514 // Track the pointer id for drag window and generate the drag state.
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08005515 const size_t id = firstMarkedBit(pointerIds);
Arthur Hung54745652022-04-20 07:17:41 +00005516 mDragState = std::make_unique<DragState>(toWindowHandle, id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005517 }
5518
Arthur Hungabbb9d82021-09-01 14:52:30 +00005519 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005520 std::shared_ptr<Connection> fromConnection = getConnectionLocked(fromToken);
5521 std::shared_ptr<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005522 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005523 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005524 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5525 "transferring touch from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005526 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Arthur Hungc539dbb2022-12-08 07:45:36 +00005527 synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection,
5528 newTargetFlags);
5529
5530 // Check if the wallpaper window should deliver the corresponding event.
5531 transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005532 *state, deviceId, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005533 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005534 } // release lock
5535
5536 // Wake up poll loop since it may need to make new input dispatching choices.
5537 mLooper->wake();
5538 return true;
5539}
5540
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005541/**
5542 * Get the touched foreground window on the given display.
5543 * Return null if there are no windows touched on that display, or if more than one foreground
5544 * window is being touched.
5545 */
5546sp<WindowInfoHandle> InputDispatcher::findTouchedForegroundWindowLocked(int32_t displayId) const {
5547 auto stateIt = mTouchStatesByDisplay.find(displayId);
5548 if (stateIt == mTouchStatesByDisplay.end()) {
5549 ALOGI("No touch state on display %" PRId32, displayId);
5550 return nullptr;
5551 }
5552
5553 const TouchState& state = stateIt->second;
5554 sp<WindowInfoHandle> touchedForegroundWindow;
5555 // If multiple foreground windows are touched, return nullptr
5556 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005557 if (window.targetFlags.test(InputTarget::Flags::FOREGROUND)) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005558 if (touchedForegroundWindow != nullptr) {
5559 ALOGI("Two or more foreground windows: %s and %s",
5560 touchedForegroundWindow->getName().c_str(),
5561 window.windowHandle->getName().c_str());
5562 return nullptr;
5563 }
5564 touchedForegroundWindow = window.windowHandle;
5565 }
5566 }
5567 return touchedForegroundWindow;
5568}
5569
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005570// Binder call
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005571bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken, int32_t displayId) {
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005572 sp<IBinder> fromToken;
5573 { // acquire lock
5574 std::scoped_lock _l(mLock);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005575 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005576 if (toWindowHandle == nullptr) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005577 ALOGW("Could not find window associated with token=%p on display %" PRId32,
5578 destChannelToken.get(), displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005579 return false;
5580 }
5581
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005582 sp<WindowInfoHandle> from = findTouchedForegroundWindowLocked(displayId);
5583 if (from == nullptr) {
5584 ALOGE("Could not find a source window in %s for %p", __func__, destChannelToken.get());
5585 return false;
5586 }
5587
5588 fromToken = from->getToken();
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005589 } // release lock
5590
5591 return transferTouchFocus(fromToken, destChannelToken);
5592}
5593
Michael Wrightd02c5b62014-02-10 15:10:22 -08005594void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005595 if (DEBUG_FOCUS) {
5596 ALOGD("Resetting and dropping all events (%s).", reason);
5597 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005598
Michael Wrightfb04fd52022-11-24 22:31:11 +00005599 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005600 synthesizeCancelationEventsForAllConnectionsLocked(options);
5601
5602 resetKeyRepeatLocked();
5603 releasePendingEventLocked();
5604 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005605 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005606
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005607 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005608 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005609}
5610
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005611void InputDispatcher::logDispatchStateLocked() const {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005612 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005613 dumpDispatchStateLocked(dump);
5614
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005615 std::istringstream stream(dump);
5616 std::string line;
5617
5618 while (std::getline(stream, line, '\n')) {
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07005619 ALOGI("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005620 }
5621}
5622
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005623std::string InputDispatcher::dumpPointerCaptureStateLocked() const {
Prabir Pradhan99987712020-11-10 18:43:05 -08005624 std::string dump;
5625
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005626 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5627 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005628
5629 std::string windowName = "None";
5630 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005631 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005632 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5633 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5634 : "token has capture without window";
5635 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005636 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005637
5638 return dump;
5639}
5640
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005641void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005642 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5643 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5644 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005645 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005646
Tiger Huang721e26f2018-07-24 22:26:19 +08005647 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5648 dump += StringPrintf(INDENT "FocusedApplications:\n");
5649 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5650 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005651 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005652 const std::chrono::duration timeout =
5653 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005654 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005655 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005656 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005657 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005658 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005659 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005660 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005661
Vishnu Nairc519ff72021-01-21 08:23:08 -08005662 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005663 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005664
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005665 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005666 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005667 for (const auto& [displayId, state] : mTouchStatesByDisplay) {
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -08005668 std::string touchStateDump = addLinePrefix(state.dump(), INDENT2);
5669 dump += INDENT2 + std::to_string(displayId) + " : " + touchStateDump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005670 }
5671 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005672 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005673 }
5674
arthurhung6d4bed92021-03-17 11:59:33 +08005675 if (mDragState) {
5676 dump += StringPrintf(INDENT "DragState:\n");
5677 mDragState->dump(dump, INDENT2);
5678 }
5679
Arthur Hungb92218b2018-08-14 12:00:21 +08005680 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005681 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5682 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5683 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5684 const auto& displayInfo = it->second;
5685 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5686 displayInfo.logicalHeight);
5687 displayInfo.transform.dump(dump, "transform", INDENT4);
5688 } else {
5689 dump += INDENT2 "No DisplayInfo found!\n";
5690 }
5691
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005692 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005693 dump += INDENT2 "Windows:\n";
5694 for (size_t i = 0; i < windowHandles.size(); i++) {
Siarhei Vishniakou366fb5b2023-12-06 11:23:41 -08005695 dump += StringPrintf(INDENT3 "%zu: %s", i,
5696 streamableToString(*windowHandles[i]).c_str());
Arthur Hungb92218b2018-08-14 12:00:21 +08005697 }
5698 } else {
5699 dump += INDENT2 "Windows: <none>\n";
5700 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005701 }
5702 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005703 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005704 }
5705
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005706 if (!mGlobalMonitorsByDisplay.empty()) {
5707 for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
5708 dump += StringPrintf(INDENT "Global monitors on display %d:\n", displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00005709 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005710 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005711 } else {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005712 dump += INDENT "Global Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005713 }
5714
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005715 const nsecs_t currentTime = now();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005716
5717 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005718 if (!mRecentQueue.empty()) {
5719 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Prabir Pradhan24047542023-11-02 17:14:59 +00005720 for (const std::shared_ptr<const EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005721 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005722 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005723 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005724 }
5725 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005726 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005727 }
5728
5729 // Dump event currently being dispatched.
5730 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005731 dump += INDENT "PendingEvent:\n";
5732 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005733 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005734 dump += StringPrintf(", age=%" PRId64 "ms\n",
5735 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005736 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005737 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005738 }
5739
5740 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005741 if (!mInboundQueue.empty()) {
5742 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Prabir Pradhan24047542023-11-02 17:14:59 +00005743 for (const std::shared_ptr<const EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005744 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005745 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005746 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005747 }
5748 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005749 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005750 }
5751
Prabir Pradhancef936d2021-07-21 16:17:52 +00005752 if (!mCommandQueue.empty()) {
5753 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5754 } else {
5755 dump += INDENT "CommandQueue: <empty>\n";
5756 }
5757
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005758 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005759 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005760 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005761 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005762 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005763 connection->inputChannel->getFd().get(),
5764 connection->getInputChannelName().c_str(),
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005765 connection->getWindowName().c_str(),
5766 ftl::enum_string(connection->status).c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005767 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005768
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005769 if (!connection->outboundQueue.empty()) {
5770 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5771 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005772 dump += dumpQueue(connection->outboundQueue, currentTime);
5773
Michael Wrightd02c5b62014-02-10 15:10:22 -08005774 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005775 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005776 }
5777
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005778 if (!connection->waitQueue.empty()) {
5779 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5780 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005781 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005782 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005783 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005784 }
Siarhei Vishniakou366fb5b2023-12-06 11:23:41 -08005785 std::string inputStateDump = streamableToString(connection->inputState);
5786 if (!inputStateDump.empty()) {
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -07005787 dump += INDENT3 "InputState: ";
Siarhei Vishniakou366fb5b2023-12-06 11:23:41 -08005788 dump += inputStateDump + "\n";
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -07005789 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005790 }
5791 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005792 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005793 }
5794
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07005795 dump += "input_flags::remove_app_switch_drops() = ";
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07005796 dump += toString(REMOVE_APP_SWITCH_DROPS);
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07005797 dump += "\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005798 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005799 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5800 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005801 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005802 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005803 }
5804
Antonio Kantek15beb512022-06-13 22:35:41 +00005805 if (!mTouchModePerDisplay.empty()) {
5806 dump += INDENT "TouchModePerDisplay:\n";
5807 for (const auto& [displayId, touchMode] : mTouchModePerDisplay) {
5808 dump += StringPrintf(INDENT2 "Display: %" PRId32 " TouchMode: %s\n", displayId,
5809 std::to_string(touchMode).c_str());
5810 }
5811 } else {
5812 dump += INDENT "TouchModePerDisplay: <none>\n";
5813 }
5814
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005815 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005816 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5817 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5818 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005819 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005820 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005821}
5822
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005823void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00005824 const size_t numMonitors = monitors.size();
5825 for (size_t i = 0; i < numMonitors; i++) {
5826 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005827 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005828 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5829 dump += "\n";
5830 }
5831}
5832
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005833class LooperEventCallback : public LooperCallback {
5834public:
5835 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5836 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5837
5838private:
5839 std::function<int(int events)> mCallback;
5840};
5841
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005842Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005843 if (DEBUG_CHANNEL_CREATION) {
5844 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5845 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005846
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005847 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005848 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005849 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005850
5851 if (result) {
5852 return base::Error(result) << "Failed to open input channel pair with name " << name;
5853 }
5854
Michael Wrightd02c5b62014-02-10 15:10:22 -08005855 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005856 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005857 const sp<IBinder>& token = serverChannel->getConnectionToken();
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005858 auto&& fd = serverChannel->getFd();
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005859 std::shared_ptr<Connection> connection =
5860 std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/false,
5861 mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005862
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005863 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5864 ALOGE("Created a new connection, but the token %p is already known", token.get());
5865 }
5866 mConnectionsByToken.emplace(token, connection);
5867
5868 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5869 this, std::placeholders::_1, token);
5870
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005871 mLooper->addFd(fd.get(), 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005872 nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005873 } // release lock
5874
5875 // Wake the looper because some connections have changed.
5876 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005877 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005878}
5879
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005880Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005881 const std::string& name,
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00005882 gui::Pid pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005883 std::shared_ptr<InputChannel> serverChannel;
5884 std::unique_ptr<InputChannel> clientChannel;
5885 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5886 if (result) {
5887 return base::Error(result) << "Failed to open input channel pair with name " << name;
5888 }
5889
Michael Wright3dd60e22019-03-27 22:06:44 +00005890 { // acquire lock
5891 std::scoped_lock _l(mLock);
5892
5893 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005894 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5895 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005896 }
5897
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005898 std::shared_ptr<Connection> connection =
5899 std::make_shared<Connection>(serverChannel, /*monitor=*/true, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005900 const sp<IBinder>& token = serverChannel->getConnectionToken();
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005901 auto&& fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005902
5903 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5904 ALOGE("Created a new connection, but the token %p is already known", token.get());
5905 }
5906 mConnectionsByToken.emplace(token, connection);
5907 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5908 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005909
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005910 mGlobalMonitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005911
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005912 mLooper->addFd(fd.get(), 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005913 nullptr);
Michael Wright3dd60e22019-03-27 22:06:44 +00005914 }
Garfield Tan15601662020-09-22 15:32:38 -07005915
Michael Wright3dd60e22019-03-27 22:06:44 +00005916 // Wake the looper because some connections have changed.
5917 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005918 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005919}
5920
Garfield Tan15601662020-09-22 15:32:38 -07005921status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005922 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005923 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005924
Harry Cutts33476232023-01-30 19:57:29 +00005925 status_t status = removeInputChannelLocked(connectionToken, /*notify=*/false);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005926 if (status) {
5927 return status;
5928 }
5929 } // release lock
5930
5931 // Wake the poll loop because removing the connection may have changed the current
5932 // synchronization state.
5933 mLooper->wake();
5934 return OK;
5935}
5936
Garfield Tan15601662020-09-22 15:32:38 -07005937status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5938 bool notify) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005939 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005940 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005941 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005942 return BAD_VALUE;
5943 }
5944
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005945 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005946
Michael Wrightd02c5b62014-02-10 15:10:22 -08005947 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005948 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005949 }
5950
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005951 mLooper->removeFd(connection->inputChannel->getFd().get());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005952
5953 nsecs_t currentTime = now();
5954 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5955
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005956 connection->status = Connection::Status::ZOMBIE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005957 return OK;
5958}
5959
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005960void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005961 for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
5962 auto& [displayId, monitors] = *it;
5963 std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
5964 return monitor.inputChannel->getConnectionToken() == connectionToken;
5965 });
Michael Wright3dd60e22019-03-27 22:06:44 +00005966
Michael Wright3dd60e22019-03-27 22:06:44 +00005967 if (monitors.empty()) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005968 it = mGlobalMonitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005969 } else {
5970 ++it;
5971 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005972 }
5973}
5974
Michael Wright3dd60e22019-03-27 22:06:44 +00005975status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005976 std::scoped_lock _l(mLock);
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00005977 return pilferPointersLocked(token);
5978}
Michael Wright3dd60e22019-03-27 22:06:44 +00005979
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00005980status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005981 const std::shared_ptr<InputChannel> requestingChannel = getInputChannelLocked(token);
5982 if (!requestingChannel) {
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07005983 LOG(WARNING)
5984 << "Attempted to pilfer pointers from an un-registered channel or invalid token";
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005985 return BAD_VALUE;
Michael Wright3dd60e22019-03-27 22:06:44 +00005986 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005987
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005988 auto [statePtr, windowPtr, displayId] = findTouchStateWindowAndDisplayLocked(token);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005989 if (statePtr == nullptr || windowPtr == nullptr) {
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07005990 LOG(WARNING)
5991 << "Attempted to pilfer points from a channel without any on-going pointer streams."
5992 " Ignoring.";
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005993 return BAD_VALUE;
5994 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005995 std::set<int32_t> deviceIds = windowPtr->getTouchingDeviceIds();
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07005996 if (deviceIds.empty()) {
5997 LOG(WARNING) << "Can't pilfer: no touching devices in window: " << windowPtr->dump();
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005998 return BAD_VALUE;
5999 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006000
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006001 for (const DeviceId deviceId : deviceIds) {
6002 TouchState& state = *statePtr;
6003 TouchedWindow& window = *windowPtr;
6004 // Send cancel events to all the input channels we're stealing from.
6005 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6006 "input channel stole pointer stream");
6007 options.deviceId = deviceId;
6008 options.displayId = displayId;
6009 std::bitset<MAX_POINTER_ID + 1> pointerIds = window.getTouchingPointers(deviceId);
6010 options.pointerIds = pointerIds;
6011 std::string canceledWindows;
6012 for (const TouchedWindow& w : state.windows) {
6013 const std::shared_ptr<InputChannel> channel =
6014 getInputChannelLocked(w.windowHandle->getToken());
6015 if (channel != nullptr && channel->getConnectionToken() != token) {
6016 synthesizeCancelationEventsForInputChannelLocked(channel, options);
6017 canceledWindows += canceledWindows.empty() ? "[" : ", ";
6018 canceledWindows += channel->getName();
6019 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006020 }
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006021 canceledWindows += canceledWindows.empty() ? "[]" : "]";
6022 LOG(INFO) << "Channel " << requestingChannel->getName()
6023 << " is stealing input gesture for device " << deviceId << " from "
6024 << canceledWindows;
6025
6026 // Prevent the gesture from being sent to any other windows.
6027 // This only blocks relevant pointers to be sent to other windows
6028 window.addPilferingPointers(deviceId, pointerIds);
6029
6030 state.cancelPointersForWindowsExcept(deviceId, pointerIds, token);
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006031 }
Michael Wright3dd60e22019-03-27 22:06:44 +00006032 return OK;
6033}
6034
Prabir Pradhan99987712020-11-10 18:43:05 -08006035void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
6036 { // acquire lock
6037 std::scoped_lock _l(mLock);
6038 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05006039 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08006040 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
6041 windowHandle != nullptr ? windowHandle->getName().c_str()
6042 : "token without window");
6043 }
6044
Vishnu Nairc519ff72021-01-21 08:23:08 -08006045 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08006046 if (focusedToken != windowToken) {
6047 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
6048 enabled ? "enable" : "disable");
6049 return;
6050 }
6051
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006052 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006053 ALOGW("Ignoring request to %s Pointer Capture: "
6054 "window has %s requested pointer capture.",
6055 enabled ? "enable" : "disable", enabled ? "already" : "not");
6056 return;
6057 }
6058
Christine Franksb768bb42021-11-29 12:11:31 -08006059 if (enabled) {
6060 if (std::find(mIneligibleDisplaysForPointerCapture.begin(),
6061 mIneligibleDisplaysForPointerCapture.end(),
6062 mFocusedDisplayId) != mIneligibleDisplaysForPointerCapture.end()) {
6063 ALOGW("Ignoring request to enable Pointer Capture: display is not eligible");
6064 return;
6065 }
6066 }
6067
Prabir Pradhan99987712020-11-10 18:43:05 -08006068 setPointerCaptureLocked(enabled);
6069 } // release lock
6070
6071 // Wake the thread to process command entries.
6072 mLooper->wake();
6073}
6074
Christine Franksb768bb42021-11-29 12:11:31 -08006075void InputDispatcher::setDisplayEligibilityForPointerCapture(int32_t displayId, bool isEligible) {
6076 { // acquire lock
6077 std::scoped_lock _l(mLock);
6078 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
6079 if (!isEligible) {
6080 mIneligibleDisplaysForPointerCapture.push_back(displayId);
6081 }
6082 } // release lock
6083}
6084
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00006085std::optional<gui::Pid> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006086 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00006087 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006088 if (monitor.inputChannel->getConnectionToken() == token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006089 return monitor.pid;
Michael Wright3dd60e22019-03-27 22:06:44 +00006090 }
6091 }
6092 }
6093 return std::nullopt;
6094}
6095
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006096std::shared_ptr<Connection> InputDispatcher::getConnectionLocked(
6097 const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07006098 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006099 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08006100 }
6101
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00006102 for (const auto& [token, connection] : mConnectionsByToken) {
6103 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006104 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006105 }
6106 }
Robert Carr4e670e52018-08-15 13:26:12 -07006107
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006108 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006109}
6110
Siarhei Vishniakouad991402020-10-28 11:40:09 -05006111std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006112 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakouad991402020-10-28 11:40:09 -05006113 if (connection == nullptr) {
6114 return "<nullptr>";
6115 }
6116 return connection->getInputChannelName();
6117}
6118
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006119void InputDispatcher::removeConnectionLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006120 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00006121 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07006122}
6123
Prabir Pradhancef936d2021-07-21 16:17:52 +00006124void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006125 const std::shared_ptr<Connection>& connection,
6126 uint32_t seq, bool handled,
6127 nsecs_t consumeTime) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006128 // Handle post-event policy actions.
Prabir Pradhan24047542023-11-02 17:14:59 +00006129 std::unique_ptr<const KeyEntry> fallbackKeyEntry;
Prabir Pradhancef936d2021-07-21 16:17:52 +00006130
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006131 { // Start critical section
6132 auto dispatchEntryIt =
6133 std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6134 [seq](auto& e) { return e->seq == seq; });
6135 if (dispatchEntryIt == connection->waitQueue.end()) {
6136 return;
6137 }
6138
6139 DispatchEntry& dispatchEntry = **dispatchEntryIt;
6140
6141 const nsecs_t eventDuration = finishTime - dispatchEntry.deliveryTime;
6142 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
6143 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
6144 ns2ms(eventDuration), dispatchEntry.eventEntry->getDescription().c_str());
6145 }
6146 if (shouldReportFinishedEvent(dispatchEntry, *connection)) {
6147 mLatencyTracker.trackFinishedEvent(dispatchEntry.eventEntry->id,
6148 connection->inputChannel->getConnectionToken(),
6149 dispatchEntry.deliveryTime, consumeTime, finishTime);
6150 }
6151
6152 if (dispatchEntry.eventEntry->type == EventEntry::Type::KEY) {
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006153 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*(dispatchEntry.eventEntry));
6154 fallbackKeyEntry =
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006155 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006156 }
6157 } // End critical section: The -LockedInterruptable methods may have released the lock.
Prabir Pradhancef936d2021-07-21 16:17:52 +00006158
6159 // Dequeue the event and start the next cycle.
6160 // Because the lock might have been released, it is possible that the
6161 // contents of the wait queue to have been drained, so we need to double-check
6162 // a few things.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006163 auto entryIt = std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6164 [seq](auto& e) { return e->seq == seq; });
6165 if (entryIt != connection->waitQueue.end()) {
6166 std::unique_ptr<DispatchEntry> dispatchEntry = std::move(*entryIt);
6167 connection->waitQueue.erase(entryIt);
6168
Prabir Pradhancef936d2021-07-21 16:17:52 +00006169 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
6170 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
6171 if (!connection->responsive) {
6172 connection->responsive = isConnectionResponsive(*connection);
6173 if (connection->responsive) {
6174 // The connection was unresponsive, and now it's responsive.
6175 processConnectionResponsiveLocked(*connection);
6176 }
6177 }
6178 traceWaitQueueLength(*connection);
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006179 if (fallbackKeyEntry && connection->status == Connection::Status::NORMAL) {
6180 const InputTarget target{.inputChannel = connection->inputChannel,
6181 .flags = dispatchEntry->targetFlags};
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006182 enqueueDispatchEntryLocked(connection, std::move(fallbackKeyEntry), target);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006183 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006184 releaseDispatchEntry(std::move(dispatchEntry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00006185 }
6186
6187 // Start the next dispatch cycle for this connection.
6188 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006189}
6190
Prabir Pradhancef936d2021-07-21 16:17:52 +00006191void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
6192 const sp<IBinder>& newToken) {
6193 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
6194 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006195 mPolicy.notifyFocusChanged(oldToken, newToken);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006196 };
6197 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006198}
6199
Prabir Pradhancef936d2021-07-21 16:17:52 +00006200void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
6201 auto command = [this, token, x, y]() REQUIRES(mLock) {
6202 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006203 mPolicy.notifyDropWindow(token, x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006204 };
6205 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08006206}
6207
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006208void InputDispatcher::onAnrLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006209 if (connection == nullptr) {
6210 LOG_ALWAYS_FATAL("Caller must check for nullness");
6211 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006212 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
6213 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006214 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006215 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006216 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006217 return;
6218 }
6219 /**
6220 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
6221 * may not be the one that caused the timeout to occur. One possibility is that window timeout
6222 * has changed. This could cause newer entries to time out before the already dispatched
6223 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
6224 * processes the events linearly. So providing information about the oldest entry seems to be
6225 * most useful.
6226 */
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006227 DispatchEntry& oldestEntry = *connection->waitQueue.front();
6228 const nsecs_t currentWait = now() - oldestEntry.deliveryTime;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006229 std::string reason =
6230 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006231 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006232 ns2ms(currentWait),
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006233 oldestEntry.eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006234 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06006235 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006236
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006237 processConnectionUnresponsiveLocked(*connection, std::move(reason));
6238
6239 // Stop waking up for events on this connection, it is already unresponsive
6240 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006241}
6242
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05006243void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
6244 std::string reason =
6245 StringPrintf("%s does not have a focused window", application->getName().c_str());
6246 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006247
Yabin Cui8eb9c552023-06-08 18:05:07 +00006248 auto command = [this, app = std::move(application)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006249 scoped_unlock unlock(mLock);
Yabin Cuiced952f2023-06-09 21:12:51 +00006250 mPolicy.notifyNoFocusedWindowAnr(app);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006251 };
6252 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00006253}
6254
chaviw98318de2021-05-19 16:45:23 -05006255void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006256 const std::string& reason) {
6257 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
6258 updateLastAnrStateLocked(windowLabel, reason);
6259}
6260
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05006261void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
6262 const std::string& reason) {
6263 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006264 updateLastAnrStateLocked(windowLabel, reason);
6265}
6266
6267void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
6268 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006269 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07006270 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006271 struct tm tm;
6272 localtime_r(&t, &tm);
6273 char timestr[64];
6274 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006275 mLastAnrState.clear();
6276 mLastAnrState += INDENT "ANR:\n";
6277 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006278 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
6279 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006280 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006281}
6282
Prabir Pradhancef936d2021-07-21 16:17:52 +00006283void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
Prabir Pradhan24047542023-11-02 17:14:59 +00006284 const KeyEntry& entry) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006285 const KeyEvent event = createKeyEvent(entry);
6286 nsecs_t delay = 0;
6287 { // release lock
6288 scoped_unlock unlock(mLock);
6289 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00006290 delay = mPolicy.interceptKeyBeforeDispatching(focusedWindowToken, event, entry.policyFlags);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006291 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
6292 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
6293 std::to_string(t.duration().count()).c_str());
6294 }
6295 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08006296
6297 if (delay < 0) {
Michael Wright5caf55a2022-11-24 22:31:42 +00006298 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00006299 } else if (delay == 0) {
Michael Wright5caf55a2022-11-24 22:31:42 +00006300 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006301 } else {
Michael Wright5caf55a2022-11-24 22:31:42 +00006302 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006303 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006304 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006305}
6306
Prabir Pradhancef936d2021-07-21 16:17:52 +00006307void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00006308 std::optional<gui::Pid> pid,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006309 std::string reason) {
Yabin Cui8eb9c552023-06-08 18:05:07 +00006310 auto command = [this, token, pid, r = std::move(reason)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006311 scoped_unlock unlock(mLock);
Yabin Cuiced952f2023-06-09 21:12:51 +00006312 mPolicy.notifyWindowUnresponsive(token, pid, r);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006313 };
6314 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006315}
6316
Prabir Pradhanedd96402022-02-15 01:46:16 -08006317void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00006318 std::optional<gui::Pid> pid) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08006319 auto command = [this, token, pid]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006320 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006321 mPolicy.notifyWindowResponsive(token, pid);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006322 };
6323 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006324}
6325
6326/**
6327 * Tell the policy that a connection has become unresponsive so that it can start ANR.
6328 * Check whether the connection of interest is a monitor or a window, and add the corresponding
6329 * command entry to the command queue.
6330 */
6331void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
6332 std::string reason) {
6333 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00006334 std::optional<gui::Pid> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006335 if (connection.monitor) {
6336 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
6337 reason.c_str());
Prabir Pradhanedd96402022-02-15 01:46:16 -08006338 pid = findMonitorPidByTokenLocked(connectionToken);
6339 } else {
6340 // The connection is a window
6341 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
6342 reason.c_str());
6343 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6344 if (handle != nullptr) {
6345 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006346 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006347 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08006348 sendWindowUnresponsiveCommandLocked(connectionToken, pid, std::move(reason));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006349}
6350
6351/**
6352 * Tell the policy that a connection has become responsive so that it can stop ANR.
6353 */
6354void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
6355 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhane59c6dc2023-06-13 19:53:03 +00006356 std::optional<gui::Pid> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006357 if (connection.monitor) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08006358 pid = findMonitorPidByTokenLocked(connectionToken);
6359 } else {
6360 // The connection is a window
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 sendWindowResponsiveCommandLocked(connectionToken, pid);
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006367}
6368
Prabir Pradhan24047542023-11-02 17:14:59 +00006369std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptable(
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006370 const std::shared_ptr<Connection>& connection, DispatchEntry& dispatchEntry,
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006371 const KeyEntry& keyEntry, bool handled) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006372 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006373 if (!handled) {
6374 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006375 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006376 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006377 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006378 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006379
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006380 // Get the fallback key state.
6381 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006382 int32_t originalKeyCode = keyEntry.keyCode;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006383 std::optional<int32_t> fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006384 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006385 connection->inputState.removeFallbackKey(originalKeyCode);
6386 }
6387
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006388 if (handled || !dispatchEntry.hasForegroundTarget()) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006389 // If the application handles the original key for which we previously
6390 // generated a fallback or if the window is not a foreground window,
6391 // then cancel the associated fallback key, if any.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006392 if (fallbackKeyCode) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006393 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006394 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6395 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
6396 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6397 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
6398 keyEntry.policyFlags);
6399 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006400 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006401 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006402
6403 mLock.unlock();
6404
Prabir Pradhana41d2442023-04-20 21:30:40 +00006405 if (const auto unhandledKeyFallback =
6406 mPolicy.dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
6407 event, keyEntry.policyFlags);
6408 unhandledKeyFallback) {
6409 event = *unhandledKeyFallback;
6410 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006411
6412 mLock.lock();
6413
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006414 // Cancel the fallback key.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006415 if (*fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00006416 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006417 "application handled the original non-fallback key "
6418 "or is no longer a foreground target, "
6419 "canceling previously dispatched fallback key");
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006420 options.keyCode = *fallbackKeyCode;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006421 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006422 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006423 connection->inputState.removeFallbackKey(originalKeyCode);
6424 }
6425 } else {
6426 // If the application did not handle a non-fallback key, first check
6427 // that we are in a good state to perform unhandled key event processing
6428 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006429 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006430 if (!fallbackKeyCode && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006431 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6432 ALOGD("Unhandled key event: Skipping unhandled key event processing "
6433 "since this is not an initial down. "
6434 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6435 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6436 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006437 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006438 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006439
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006440 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006441 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6442 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
6443 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6444 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6445 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006446 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006447
6448 mLock.unlock();
6449
Prabir Pradhana41d2442023-04-20 21:30:40 +00006450 bool fallback = false;
6451 if (auto fb = mPolicy.dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
6452 event, keyEntry.policyFlags);
6453 fb) {
6454 fallback = true;
6455 event = *fb;
6456 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006457
6458 mLock.lock();
6459
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08006460 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006461 connection->inputState.removeFallbackKey(originalKeyCode);
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006462 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006463 }
6464
6465 // Latch the fallback keycode for this key on an initial down.
6466 // The fallback keycode cannot change at any other point in the lifecycle.
6467 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006468 if (fallback) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006469 *fallbackKeyCode = event.getKeyCode();
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006470 } else {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006471 *fallbackKeyCode = AKEYCODE_UNKNOWN;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006472 }
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006473 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006474 }
6475
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006476 ALOG_ASSERT(fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006477
6478 // Cancel the fallback key if the policy decides not to send it anymore.
6479 // We will continue to dispatch the key to the policy but we will no
6480 // longer dispatch a fallback key to the application.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006481 if (*fallbackKeyCode != AKEYCODE_UNKNOWN &&
6482 (!fallback || *fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006483 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6484 if (fallback) {
6485 ALOGD("Unhandled key event: Policy requested to send key %d"
6486 "as a fallback for %d, but on the DOWN it had requested "
6487 "to send %d instead. Fallback canceled.",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006488 event.getKeyCode(), originalKeyCode, *fallbackKeyCode);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006489 } else {
6490 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6491 "but on the DOWN it had requested to send %d. "
6492 "Fallback canceled.",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006493 originalKeyCode, *fallbackKeyCode);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006494 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006495 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006496
Michael Wrightfb04fd52022-11-24 22:31:11 +00006497 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006498 "canceling fallback, policy no longer desires it");
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006499 options.keyCode = *fallbackKeyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006500 synthesizeCancelationEventsForConnectionLocked(connection, options);
6501
6502 fallback = false;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006503 *fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006504 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006505 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006506 }
6507 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006508
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006509 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6510 {
6511 std::string msg;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006512 const std::map<int32_t, int32_t>& fallbackKeys =
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006513 connection->inputState.getFallbackKeys();
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006514 for (const auto& [key, value] : fallbackKeys) {
6515 msg += StringPrintf(", %d->%d", key, value);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006516 }
6517 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6518 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006519 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006520 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006521
6522 if (fallback) {
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006523 // Return the fallback key that we want dispatched to the channel.
6524 std::unique_ptr<KeyEntry> newEntry =
6525 std::make_unique<KeyEntry>(mIdGenerator.nextId(), keyEntry.injectionState,
6526 event.getEventTime(), event.getDeviceId(),
6527 event.getSource(), event.getDisplayId(),
6528 keyEntry.policyFlags, keyEntry.action,
6529 event.getFlags() | AKEY_EVENT_FLAG_FALLBACK,
6530 *fallbackKeyCode, event.getScanCode(),
6531 event.getMetaState(), event.getRepeatCount(),
6532 event.getDownTime());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006533 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6534 ALOGD("Unhandled key event: Dispatching fallback key. "
6535 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006536 originalKeyCode, *fallbackKeyCode, keyEntry.metaState);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006537 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006538 return newEntry;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006539 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006540 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6541 ALOGD("Unhandled key event: No fallback key.");
6542 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006543
6544 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006545 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006546 }
6547 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006548 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08006549}
6550
Michael Wrightd02c5b62014-02-10 15:10:22 -08006551void InputDispatcher::traceInboundQueueLengthLocked() {
6552 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006553 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006554 }
6555}
6556
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006557void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006558 if (ATRACE_ENABLED()) {
6559 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006560 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6561 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006562 }
6563}
6564
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006565void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006566 if (ATRACE_ENABLED()) {
6567 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006568 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6569 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006570 }
6571}
6572
Siarhei Vishniakou5e20f272023-06-08 17:24:44 -07006573void InputDispatcher::dump(std::string& dump) const {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006574 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006575
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006576 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006577 dumpDispatchStateLocked(dump);
6578
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006579 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006580 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006581 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006582 }
6583}
6584
6585void InputDispatcher::monitor() {
6586 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006587 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006588 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006589 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006590}
6591
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006592/**
6593 * Wake up the dispatcher and wait until it processes all events and commands.
6594 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6595 * this method can be safely called from any thread, as long as you've ensured that
6596 * the work you are interested in completing has already been queued.
6597 */
Siarhei Vishniakoua66d65e2023-06-16 10:32:51 -07006598bool InputDispatcher::waitForIdle() const {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006599 /**
6600 * Timeout should represent the longest possible time that a device might spend processing
6601 * events and commands.
6602 */
6603 constexpr std::chrono::duration TIMEOUT = 100ms;
6604 std::unique_lock lock(mLock);
6605 mLooper->wake();
6606 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6607 return result == std::cv_status::no_timeout;
6608}
6609
Vishnu Naire798b472020-07-23 13:52:21 -07006610/**
6611 * Sets focus to the window identified by the token. This must be called
6612 * after updating any input window handles.
6613 *
6614 * Params:
6615 * request.token - input channel token used to identify the window that should gain focus.
6616 * request.focusedToken - the token that the caller expects currently to be focused. If the
6617 * specified token does not match the currently focused window, this request will be dropped.
6618 * If the specified focused token matches the currently focused window, the call will succeed.
6619 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6620 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6621 * when requesting the focus change. This determines which request gets
6622 * precedence if there is a focus change request from another source such as pointer down.
6623 */
Vishnu Nair958da932020-08-21 17:12:37 -07006624void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6625 { // acquire lock
6626 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006627 std::optional<FocusResolver::FocusChanges> changes =
6628 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6629 if (changes) {
6630 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006631 }
6632 } // release lock
6633 // Wake up poll loop since it may need to make new input dispatching choices.
6634 mLooper->wake();
6635}
6636
Vishnu Nairc519ff72021-01-21 08:23:08 -08006637void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6638 if (changes.oldFocus) {
6639 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006640 if (focusedInputChannel) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00006641 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006642 "focus left window");
6643 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Harry Cutts33476232023-01-30 19:57:29 +00006644 enqueueFocusEventLocked(changes.oldFocus, /*hasFocus=*/false, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006645 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006646 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006647 if (changes.newFocus) {
Siarhei Vishniakouc033dfb2023-10-03 10:45:16 -07006648 resetNoFocusedWindowTimeoutLocked();
Harry Cutts33476232023-01-30 19:57:29 +00006649 enqueueFocusEventLocked(changes.newFocus, /*hasFocus=*/true, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006650 }
6651
Prabir Pradhan99987712020-11-10 18:43:05 -08006652 // If a window has pointer capture, then it must have focus. We need to ensure that this
6653 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6654 // If the window loses focus before it loses pointer capture, then the window can be in a state
6655 // where it has pointer capture but not focus, violating the contract. Therefore we must
6656 // dispatch the pointer capture event before the focus event. Since focus events are added to
6657 // the front of the queue (above), we add the pointer capture event to the front of the queue
6658 // after the focus events are added. This ensures the pointer capture event ends up at the
6659 // front.
6660 disablePointerCaptureForcedLocked();
6661
Vishnu Nairc519ff72021-01-21 08:23:08 -08006662 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006663 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006664 }
6665}
Vishnu Nair958da932020-08-21 17:12:37 -07006666
Prabir Pradhan99987712020-11-10 18:43:05 -08006667void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006668 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006669 return;
6670 }
6671
6672 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6673
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006674 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006675 setPointerCaptureLocked(false);
6676 }
6677
6678 if (!mWindowTokenWithPointerCapture) {
6679 // No need to send capture changes because no window has capture.
6680 return;
6681 }
6682
6683 if (mPendingEvent != nullptr) {
6684 // Move the pending event to the front of the queue. This will give the chance
6685 // for the pending event to be dropped if it is a captured event.
6686 mInboundQueue.push_front(mPendingEvent);
6687 mPendingEvent = nullptr;
6688 }
6689
6690 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006691 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006692 mInboundQueue.push_front(std::move(entry));
6693}
6694
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006695void InputDispatcher::setPointerCaptureLocked(bool enable) {
6696 mCurrentPointerCaptureRequest.enable = enable;
6697 mCurrentPointerCaptureRequest.seq++;
6698 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006699 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006700 mPolicy.setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006701 };
6702 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006703}
6704
Vishnu Nair599f1412021-06-21 10:39:58 -07006705void InputDispatcher::displayRemoved(int32_t displayId) {
6706 { // acquire lock
6707 std::scoped_lock _l(mLock);
6708 // Set an empty list to remove all handles from the specific display.
Harry Cutts101ee9b2023-07-06 18:04:14 +00006709 setInputWindowsLocked(/*windowInfoHandles=*/{}, displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006710 setFocusedApplicationLocked(displayId, nullptr);
6711 // Call focus resolver to clean up stale requests. This must be called after input windows
6712 // have been removed for the removed display.
6713 mFocusResolver.displayRemoved(displayId);
Christine Franksb768bb42021-11-29 12:11:31 -08006714 // Reset pointer capture eligibility, regardless of previous state.
6715 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
Antonio Kantek15beb512022-06-13 22:35:41 +00006716 // Remove the associated touch mode state.
6717 mTouchModePerDisplay.erase(displayId);
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07006718 mVerifiersByDisplay.erase(displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006719 } // release lock
6720
6721 // Wake up poll loop since it may need to make new input dispatching choices.
6722 mLooper->wake();
6723}
6724
Patrick Williamsd828f302023-04-28 17:52:08 -05006725void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update) {
chaviw15fab6f2021-06-07 14:15:52 -05006726 // The listener sends the windows as a flattened array. Separate the windows by display for
6727 // more convenient parsing.
6728 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
Patrick Williamsd828f302023-04-28 17:52:08 -05006729 for (const auto& info : update.windowInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006730 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07006731 handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
chaviw15fab6f2021-06-07 14:15:52 -05006732 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006733
6734 { // acquire lock
6735 std::scoped_lock _l(mLock);
Prabir Pradhan814fe082022-07-22 20:22:18 +00006736
6737 // Ensure that we have an entry created for all existing displays so that if a displayId has
6738 // no windows, we can tell that the windows were removed from the display.
6739 for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
6740 handlesPerDisplay[displayId];
6741 }
6742
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006743 mDisplayInfos.clear();
Patrick Williamsd828f302023-04-28 17:52:08 -05006744 for (const auto& displayInfo : update.displayInfos) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006745 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6746 }
6747
6748 for (const auto& [displayId, handles] : handlesPerDisplay) {
6749 setInputWindowsLocked(handles, displayId);
6750 }
Patrick Williams9464b2c2023-05-23 11:22:04 -05006751
6752 if (update.vsyncId < mWindowInfosVsyncId) {
6753 ALOGE("Received out of order window infos update. Last update vsync id: %" PRId64
6754 ", current update vsync id: %" PRId64,
6755 mWindowInfosVsyncId, update.vsyncId);
6756 }
6757 mWindowInfosVsyncId = update.vsyncId;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006758 }
6759 // Wake up poll loop since it may need to make new input dispatching choices.
6760 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006761}
6762
Vishnu Nair062a8672021-09-03 16:07:44 -07006763bool InputDispatcher::shouldDropInput(
6764 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006765 if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
6766 (windowHandle->getInfo()->inputConfig.test(
6767 WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
Vishnu Nair062a8672021-09-03 16:07:44 -07006768 isWindowObscuredLocked(windowHandle))) {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006769 ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on "
6770 "display %" PRId32 ".",
Vishnu Nair062a8672021-09-03 16:07:44 -07006771 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006772 windowHandle->getInfo()->inputConfig.string().c_str(),
Vishnu Nair062a8672021-09-03 16:07:44 -07006773 windowHandle->getInfo()->displayId);
6774 return true;
6775 }
6776 return false;
6777}
6778
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006779void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
Patrick Williamsd828f302023-04-28 17:52:08 -05006780 const gui::WindowInfosUpdate& update) {
6781 mDispatcher.onWindowInfosChanged(update);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006782}
6783
Arthur Hungdfd528e2021-12-08 13:23:04 +00006784void InputDispatcher::cancelCurrentTouch() {
6785 {
6786 std::scoped_lock _l(mLock);
6787 ALOGD("Canceling all ongoing pointer gestures on all displays.");
Michael Wrightfb04fd52022-11-24 22:31:11 +00006788 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Arthur Hungdfd528e2021-12-08 13:23:04 +00006789 "cancel current touch");
6790 synthesizeCancelationEventsForAllConnectionsLocked(options);
6791
6792 mTouchStatesByDisplay.clear();
Arthur Hungdfd528e2021-12-08 13:23:04 +00006793 }
6794 // Wake up poll loop since there might be work to do.
6795 mLooper->wake();
6796}
6797
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08006798void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout) {
6799 std::scoped_lock _l(mLock);
6800 mMonitorDispatchingTimeout = timeout;
6801}
6802
Arthur Hungc539dbb2022-12-08 07:45:36 +00006803void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
6804 const sp<WindowInfoHandle>& oldWindowHandle,
6805 const sp<WindowInfoHandle>& newWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006806 TouchState& state, int32_t deviceId, int32_t pointerId,
Siarhei Vishniakoubf880522023-05-01 11:03:22 -07006807 std::vector<InputTarget>& targets) const {
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08006808 std::bitset<MAX_POINTER_ID + 1> pointerIds;
6809 pointerIds.set(pointerId);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006810 const bool oldHasWallpaper = oldWindowHandle->getInfo()->inputConfig.test(
6811 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6812 const bool newHasWallpaper = targetFlags.test(InputTarget::Flags::FOREGROUND) &&
6813 newWindowHandle->getInfo()->inputConfig.test(
6814 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6815 const sp<WindowInfoHandle> oldWallpaper =
6816 oldHasWallpaper ? state.getWallpaperWindow() : nullptr;
6817 const sp<WindowInfoHandle> newWallpaper =
6818 newHasWallpaper ? findWallpaperWindowBelow(newWindowHandle) : nullptr;
6819 if (oldWallpaper == newWallpaper) {
6820 return;
6821 }
6822
6823 if (oldWallpaper != nullptr) {
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08006824 const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper);
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006825 addPointerWindowTargetLocked(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT,
6826 oldTouchedWindow.targetFlags, pointerIds,
6827 oldTouchedWindow.getDownTimeInTarget(deviceId), targets);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006828 state.removeTouchingPointerFromWindow(deviceId, pointerId, oldWallpaper);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006829 }
6830
6831 if (newWallpaper != nullptr) {
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006832 state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::SLIPPERY_ENTER,
6833 InputTarget::Flags::WINDOW_IS_OBSCURED |
Arthur Hungc539dbb2022-12-08 07:45:36 +00006834 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006835 deviceId, pointerIds);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006836 }
6837}
6838
6839void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags,
6840 ftl::Flags<InputTarget::Flags> newTargetFlags,
6841 const sp<WindowInfoHandle> fromWindowHandle,
6842 const sp<WindowInfoHandle> toWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006843 TouchState& state, int32_t deviceId,
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08006844 std::bitset<MAX_POINTER_ID + 1> pointerIds) {
Arthur Hungc539dbb2022-12-08 07:45:36 +00006845 const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
6846 fromWindowHandle->getInfo()->inputConfig.test(
6847 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6848 const bool newHasWallpaper = newTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
6849 toWindowHandle->getInfo()->inputConfig.test(
6850 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6851
6852 const sp<WindowInfoHandle> oldWallpaper =
6853 oldHasWallpaper ? state.getWallpaperWindow() : nullptr;
6854 const sp<WindowInfoHandle> newWallpaper =
6855 newHasWallpaper ? findWallpaperWindowBelow(toWindowHandle) : nullptr;
6856 if (oldWallpaper == newWallpaper) {
6857 return;
6858 }
6859
6860 if (oldWallpaper != nullptr) {
6861 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6862 "transferring touch focus to another window");
6863 state.removeWindowByToken(oldWallpaper->getToken());
6864 synthesizeCancelationEventsForWindowLocked(oldWallpaper, options);
6865 }
6866
6867 if (newWallpaper != nullptr) {
6868 nsecs_t downTimeInTarget = now();
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006869 ftl::Flags<InputTarget::Flags> wallpaperFlags = oldTargetFlags & InputTarget::Flags::SPLIT;
Arthur Hungc539dbb2022-12-08 07:45:36 +00006870 wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED |
6871 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +00006872 state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
6873 deviceId, pointerIds, downTimeInTarget);
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006874 std::shared_ptr<Connection> wallpaperConnection =
6875 getConnectionLocked(newWallpaper->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00006876 if (wallpaperConnection != nullptr) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006877 std::shared_ptr<Connection> toConnection =
6878 getConnectionLocked(toWindowHandle->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00006879 toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState);
6880 synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, wallpaperConnection,
6881 wallpaperFlags);
6882 }
6883 }
6884}
6885
6886sp<WindowInfoHandle> InputDispatcher::findWallpaperWindowBelow(
6887 const sp<WindowInfoHandle>& windowHandle) const {
6888 const std::vector<sp<WindowInfoHandle>>& windowHandles =
6889 getWindowHandlesLocked(windowHandle->getInfo()->displayId);
6890 bool foundWindow = false;
6891 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
6892 if (!foundWindow && otherHandle != windowHandle) {
6893 continue;
6894 }
6895 if (windowHandle == otherHandle) {
6896 foundWindow = true;
6897 continue;
6898 }
6899
6900 if (otherHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::IS_WALLPAPER)) {
6901 return otherHandle;
6902 }
6903 }
6904 return nullptr;
6905}
6906
Siarhei Vishniakoufa2a0492023-11-14 13:13:18 -08006907void InputDispatcher::setKeyRepeatConfiguration(std::chrono::nanoseconds timeout,
6908 std::chrono::nanoseconds delay) {
Nergi Rahardi730cf3c2023-04-13 12:41:17 +09006909 std::scoped_lock _l(mLock);
6910
Siarhei Vishniakoufa2a0492023-11-14 13:13:18 -08006911 mConfig.keyRepeatTimeout = timeout.count();
6912 mConfig.keyRepeatDelay = delay.count();
Nergi Rahardi730cf3c2023-04-13 12:41:17 +09006913}
6914
Prabir Pradhan64f21d22023-11-28 21:19:42 +00006915bool InputDispatcher::isPointerInWindow(const sp<android::IBinder>& token, int32_t displayId,
6916 DeviceId deviceId, int32_t pointerId) {
6917 std::scoped_lock _l(mLock);
6918 auto touchStateIt = mTouchStatesByDisplay.find(displayId);
6919 if (touchStateIt == mTouchStatesByDisplay.end()) {
6920 return false;
6921 }
6922 for (const TouchedWindow& window : touchStateIt->second.windows) {
6923 if (window.windowHandle->getToken() == token &&
6924 (window.hasTouchingPointer(deviceId, pointerId) ||
6925 window.hasHoveringPointer(deviceId, pointerId))) {
6926 return true;
6927 }
6928 }
6929 return false;
6930}
6931
Garfield Tane84e6f92019-08-29 17:28:41 -07006932} // namespace android::inputdispatcher