blob: 4a9b67e2ccbcfc361891043b21aa13812b3c339e [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
Michael Wright2b3c3302018-03-02 17:19:13 +000022#include <android-base/chrono_utils.h>
Siarhei Vishniakoud010b012023-01-18 15:00:53 -080023#include <android-base/logging.h>
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080024#include <android-base/properties.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080025#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050026#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070027#include <binder/Binder.h>
Ameer Armalycff4fa52023-10-04 23:45:11 +000028#include <com_android_input_flags.h>
Dominik Laskowski75788452021-02-09 18:51:25 -080029#include <ftl/enum.h>
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -070030#include <log/log_event_list.h>
Siarhei Vishniakou31977182022-09-30 08:51:23 -070031#if defined(__ANDROID__)
chaviw15fab6f2021-06-07 14:15:52 -050032#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou31977182022-09-30 08:51:23 -070033#endif
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080034#include <input/InputDevice.h>
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -080035#include <input/PrintTools.h>
Prabir Pradhana37bad12023-08-18 15:55:32 +000036#include <input/TraceTools.h>
tyiu1573a672023-02-21 22:38:32 +000037#include <openssl/mem.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070038#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010039#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070040#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080041
Michael Wright44753b12020-07-08 13:48:11 +010042#include <cerrno>
43#include <cinttypes>
44#include <climits>
45#include <cstddef>
46#include <ctime>
47#include <queue>
48#include <sstream>
49
Asmita Poddardd9a6cd2023-09-26 15:35:12 +000050#include "../InputDeviceMetricsSource.h"
51
Michael Wright44753b12020-07-08 13:48:11 +010052#include "Connection.h"
Arthur Hung1a1007b2022-05-11 07:15:01 +000053#include "DebugConfig.h"
Chris Yef59a2f42020-10-16 12:55:26 -070054#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010055
Michael Wrightd02c5b62014-02-10 15:10:22 -080056#define INDENT " "
57#define INDENT2 " "
58#define INDENT3 " "
59#define INDENT4 " "
60
Siarhei Vishniakou253f4642022-11-09 13:42:06 -080061using namespace android::ftl::flag_operators;
Siarhei Vishniakou23740b92023-04-21 11:30:20 -070062using android::base::Error;
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080063using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000064using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080065using android::base::StringPrintf;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -070066using android::gui::DisplayInfo;
chaviw98318de2021-05-19 16:45:23 -050067using android::gui::FocusRequest;
68using android::gui::TouchOcclusionMode;
69using android::gui::WindowInfo;
70using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080071using android::os::InputEventInjectionResult;
72using android::os::InputEventInjectionSync;
Ameer Armalycff4fa52023-10-04 23:45:11 +000073namespace input_flags = com::android::input::flags;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080074
Siarhei Vishniakou17f12282023-11-02 13:40:29 -070075static const bool REMOVE_APP_SWITCH_DROPS = input_flags::remove_app_switch_drops();
76
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 Vishniakoud38a1e02023-07-18 11:55:17 -0700129bool isEmpty(const std::stringstream& ss) {
130 return ss.rdbuf()->in_avail() == 0;
131}
132
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700133inline const std::string binderToString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000134 if (binder == nullptr) {
135 return "<null>";
136 }
137 return StringPrintf("%p", binder.get());
138}
139
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000140static std::string uidString(const gui::Uid& uid) {
141 return uid.toString();
142}
143
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700144Result<void> checkKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800145 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700146 case AKEY_EVENT_ACTION_DOWN:
147 case AKEY_EVENT_ACTION_UP:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700148 return {};
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700149 default:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700150 return Error() << "Key event has invalid action code " << action;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800151 }
152}
153
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700154Result<void> validateKeyEvent(int32_t action) {
155 return checkKeyAction(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800156}
157
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700158Result<void> checkMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800159 switch (MotionEvent::getActionMasked(action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700160 case AMOTION_EVENT_ACTION_DOWN:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700161 case AMOTION_EVENT_ACTION_UP: {
162 if (pointerCount != 1) {
163 return Error() << "invalid pointer count " << pointerCount;
164 }
165 return {};
166 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700167 case AMOTION_EVENT_ACTION_MOVE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700168 case AMOTION_EVENT_ACTION_HOVER_ENTER:
169 case AMOTION_EVENT_ACTION_HOVER_MOVE:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700170 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
171 if (pointerCount < 1) {
172 return Error() << "invalid pointer count " << pointerCount;
173 }
174 return {};
175 }
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800176 case AMOTION_EVENT_ACTION_CANCEL:
177 case AMOTION_EVENT_ACTION_OUTSIDE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700178 case AMOTION_EVENT_ACTION_SCROLL:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700179 return {};
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700180 case AMOTION_EVENT_ACTION_POINTER_DOWN:
181 case AMOTION_EVENT_ACTION_POINTER_UP: {
Siarhei Vishniakou2f61bdc2022-12-02 08:55:51 -0800182 const int32_t index = MotionEvent::getActionIndex(action);
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700183 if (index < 0) {
184 return Error() << "invalid index " << index << " for "
185 << MotionEvent::actionToString(action);
186 }
187 if (index >= pointerCount) {
188 return Error() << "invalid index " << index << " for pointerCount " << pointerCount;
189 }
190 if (pointerCount <= 1) {
191 return Error() << "invalid pointer count " << pointerCount << " for "
192 << MotionEvent::actionToString(action);
193 }
194 return {};
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700195 }
196 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700197 case AMOTION_EVENT_ACTION_BUTTON_RELEASE: {
198 if (actionButton == 0) {
199 return Error() << "action button should be nonzero for "
200 << MotionEvent::actionToString(action);
201 }
202 return {};
203 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700204 default:
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700205 return Error() << "invalid action " << action;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800206 }
207}
208
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000209int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500210 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
211}
212
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700213Result<void> validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
214 const PointerProperties* pointerProperties) {
215 Result<void> actionCheck = checkMotionAction(action, actionButton, pointerCount);
216 if (!actionCheck.ok()) {
217 return actionCheck;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800218 }
219 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700220 return Error() << "Motion event has invalid pointer count " << pointerCount
221 << "; value must be between 1 and " << MAX_POINTERS << ".";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800222 }
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800223 std::bitset<MAX_POINTER_ID + 1> pointerIdBits;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800224 for (size_t i = 0; i < pointerCount; i++) {
225 int32_t id = pointerProperties[i].id;
226 if (id < 0 || id > MAX_POINTER_ID) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700227 return Error() << "Motion event has invalid pointer id " << id
228 << "; value must be between 0 and " << MAX_POINTER_ID;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800229 }
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800230 if (pointerIdBits.test(id)) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700231 return Error() << "Motion event has duplicate pointer id " << id;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800232 }
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800233 pointerIdBits.set(id);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800234 }
Siarhei Vishniakou23740b92023-04-21 11:30:20 -0700235 return {};
236}
237
238Result<void> validateInputEvent(const InputEvent& event) {
239 switch (event.getType()) {
240 case InputEventType::KEY: {
241 const KeyEvent& key = static_cast<const KeyEvent&>(event);
242 const int32_t action = key.getAction();
243 return validateKeyEvent(action);
244 }
245 case InputEventType::MOTION: {
246 const MotionEvent& motion = static_cast<const MotionEvent&>(event);
247 const int32_t action = motion.getAction();
248 const size_t pointerCount = motion.getPointerCount();
249 const PointerProperties* pointerProperties = motion.getPointerProperties();
250 const int32_t actionButton = motion.getActionButton();
251 return validateMotionEvent(action, actionButton, pointerCount, pointerProperties);
252 }
253 default: {
254 return {};
255 }
256 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800257}
258
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000259std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800260 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000261 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800262 }
263
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000264 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800265 bool first = true;
266 Region::const_iterator cur = region.begin();
267 Region::const_iterator const tail = region.end();
268 while (cur != tail) {
269 if (first) {
270 first = false;
271 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800272 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800273 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800274 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800275 cur++;
276 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000277 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800278}
279
Prabir Pradhan8c90d782023-09-15 21:16:44 +0000280std::string dumpQueue(const std::deque<std::unique_ptr<DispatchEntry>>& queue,
281 nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500282 constexpr size_t maxEntries = 50; // max events to print
283 constexpr size_t skipBegin = maxEntries / 2;
284 const size_t skipEnd = queue.size() - maxEntries / 2;
285 // skip from maxEntries / 2 ... size() - maxEntries/2
286 // only print from 0 .. skipBegin and then from skipEnd .. size()
287
288 std::string dump;
289 for (size_t i = 0; i < queue.size(); i++) {
290 const DispatchEntry& entry = *queue[i];
291 if (i >= skipBegin && i < skipEnd) {
292 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
293 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
294 continue;
295 }
296 dump.append(INDENT4);
297 dump += entry.eventEntry->getDescription();
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +0000298 dump += StringPrintf(", seq=%" PRIu32 ", targetFlags=%s, age=%" PRId64 "ms", entry.seq,
299 entry.targetFlags.string().c_str(),
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500300 ns2ms(currentTime - entry.eventEntry->eventTime));
301 if (entry.deliveryTime != 0) {
302 // This entry was delivered, so add information on how long we've been waiting
303 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
304 }
305 dump.append("\n");
306 }
307 return dump;
308}
309
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700310/**
311 * Find the entry in std::unordered_map by key, and return it.
312 * If the entry is not found, return a default constructed entry.
313 *
314 * Useful when the entries are vectors, since an empty vector will be returned
315 * if the entry is not found.
316 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
317 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700318template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000319V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700320 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700321 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800322}
323
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000324bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700325 if (first == second) {
326 return true;
327 }
328
329 if (first == nullptr || second == nullptr) {
330 return false;
331 }
332
333 return first->getToken() == second->getToken();
334}
335
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000336bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000337 if (first == nullptr || second == nullptr) {
338 return false;
339 }
340 return first->applicationInfo.token != nullptr &&
341 first->applicationInfo.token == second->applicationInfo.token;
342}
343
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800344template <typename T>
345size_t firstMarkedBit(T set) {
346 // TODO: replace with std::countr_zero from <bit> when that's available
347 LOG_ALWAYS_FATAL_IF(set.none());
348 size_t i = 0;
349 while (!set.test(i)) {
350 i++;
351 }
352 return i;
353}
354
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800355std::unique_ptr<DispatchEntry> createDispatchEntry(
Prabir Pradhan24047542023-11-02 17:14:59 +0000356 const InputTarget& inputTarget, std::shared_ptr<const EventEntry> eventEntry,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800357 ftl::Flags<InputTarget::Flags> inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700358 if (inputTarget.useDefaultPointerTransform()) {
359 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700360 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700361 inputTarget.displayTransform,
362 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000363 }
364
365 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
366 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
367
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700368 std::vector<PointerCoords> pointerCoords;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700369 pointerCoords.resize(motionEntry.getPointerCount());
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000370
371 // Use the first pointer information to normalize all other pointers. This could be any pointer
372 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700373 // uses the transform for the normalized pointer.
374 const ui::Transform& firstPointerTransform =
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800375 inputTarget.pointerTransforms[firstMarkedBit(inputTarget.pointerIds)];
chaviw1ff3d1e2020-07-01 15:53:47 -0700376 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000377
378 // Iterate through all pointers in the event to normalize against the first.
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700379 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount(); pointerIndex++) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000380 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
381 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700382 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000383
384 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700385 // First, apply the current pointer's transform to update the coordinates into
386 // window space.
387 pointerCoords[pointerIndex].transform(currTransform);
388 // Next, apply the inverse transform of the normalized coordinates so the
389 // current coordinates are transformed into the normalized coordinate space.
390 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000391 }
392
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700393 std::unique_ptr<MotionEntry> combinedMotionEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +0000394 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.injectionState,
395 motionEntry.eventTime, motionEntry.deviceId,
396 motionEntry.source, motionEntry.displayId,
397 motionEntry.policyFlags, motionEntry.action,
398 motionEntry.actionButton, motionEntry.flags,
399 motionEntry.metaState, motionEntry.buttonState,
400 motionEntry.classification, motionEntry.edgeFlags,
401 motionEntry.xPrecision, motionEntry.yPrecision,
402 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
403 motionEntry.downTime, motionEntry.pointerProperties,
404 pointerCoords);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000405
406 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700407 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700408 firstPointerTransform, inputTarget.displayTransform,
409 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000410 return dispatchEntry;
411}
412
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000413status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
414 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700415 std::unique_ptr<InputChannel> uniqueServerChannel;
416 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
417
418 serverChannel = std::move(uniqueServerChannel);
419 return result;
420}
421
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500422template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000423bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500424 if (lhs == nullptr && rhs == nullptr) {
425 return true;
426 }
427 if (lhs == nullptr || rhs == nullptr) {
428 return false;
429 }
430 return *lhs == *rhs;
431}
432
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000433KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000434 KeyEvent event;
435 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
436 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
437 entry.repeatCount, entry.downTime, entry.eventTime);
438 return event;
439}
440
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000441bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000442 // Do not keep track of gesture monitors. They receive every event and would disproportionately
443 // affect the statistics.
444 if (connection.monitor) {
445 return false;
446 }
447 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
448 if (!connection.responsive) {
449 return false;
450 }
451 return true;
452}
453
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000454bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000455 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
456 const int32_t& inputEventId = eventEntry.id;
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000457 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
458 return false;
459 }
460 // Only track latency for events that originated from hardware
461 if (eventEntry.isSynthesized()) {
462 return false;
463 }
464 const EventEntry::Type& inputEventEntryType = eventEntry.type;
465 if (inputEventEntryType == EventEntry::Type::KEY) {
466 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
467 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
468 return false;
469 }
470 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
471 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
472 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
473 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
474 return false;
475 }
476 } else {
477 // Not a key or a motion
478 return false;
479 }
480 if (!shouldReportMetricsForConnection(connection)) {
481 return false;
482 }
483 return true;
484}
485
Prabir Pradhancef936d2021-07-21 16:17:52 +0000486/**
487 * Connection is responsive if it has no events in the waitQueue that are older than the
488 * current time.
489 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000490bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000491 const nsecs_t currentTime = now();
Prabir Pradhan8c90d782023-09-15 21:16:44 +0000492 for (const auto& dispatchEntry : connection.waitQueue) {
493 if (dispatchEntry->timeoutTime < currentTime) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000494 return false;
495 }
496 }
497 return true;
498}
499
Antonio Kantekf16f2832021-09-28 04:39:20 +0000500// Returns true if the event type passed as argument represents a user activity.
501bool isUserActivityEvent(const EventEntry& eventEntry) {
502 switch (eventEntry.type) {
Josep del Riob3981622023-04-18 15:49:45 +0000503 case EventEntry::Type::CONFIGURATION_CHANGED:
504 case EventEntry::Type::DEVICE_RESET:
505 case EventEntry::Type::DRAG:
Antonio Kantekf16f2832021-09-28 04:39:20 +0000506 case EventEntry::Type::FOCUS:
507 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Antonio Kantekf16f2832021-09-28 04:39:20 +0000508 case EventEntry::Type::SENSOR:
Josep del Riob3981622023-04-18 15:49:45 +0000509 case EventEntry::Type::TOUCH_MODE_CHANGED:
Antonio Kantekf16f2832021-09-28 04:39:20 +0000510 return false;
Antonio Kantekf16f2832021-09-28 04:39:20 +0000511 case EventEntry::Type::KEY:
512 case EventEntry::Type::MOTION:
513 return true;
514 }
515}
516
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800517// Returns true if the given window can accept pointer events at the given display location.
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000518bool windowAcceptsTouchAt(const WindowInfo& windowInfo, int32_t displayId, float x, float y,
Prabir Pradhan33e3baa2022-12-06 20:30:22 +0000519 bool isStylus, const ui::Transform& displayTransform) {
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800520 const auto inputConfig = windowInfo.inputConfig;
521 if (windowInfo.displayId != displayId ||
522 inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800523 return false;
524 }
Prabir Pradhand65552b2021-10-07 11:23:50 -0700525 const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800526 if (inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800527 return false;
528 }
Prabir Pradhan33e3baa2022-12-06 20:30:22 +0000529
530 // Window Manager works in the logical display coordinate space. When it specifies bounds for a
531 // window as (l, t, r, b), the range of x in [l, r) and y in [t, b) are considered to be inside
532 // the window. Points on the right and bottom edges should not be inside the window, so we need
533 // to be careful about performing a hit test when the display is rotated, since the "right" and
534 // "bottom" of the window will be different in the display (un-rotated) space compared to in the
535 // logical display in which WM determined the bounds. Perform the hit test in the logical
536 // display space to ensure these edges are considered correctly in all orientations.
537 const auto touchableRegion = displayTransform.transform(windowInfo.touchableRegion);
538 const auto p = displayTransform.transform(x, y);
539 if (!touchableRegion.contains(std::floor(p.x), std::floor(p.y))) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800540 return false;
541 }
542 return true;
543}
544
Prabir Pradhand65552b2021-10-07 11:23:50 -0700545bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
546 return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
Prabir Pradhane5626962022-10-27 20:30:53 +0000547 isStylusToolType(entry.pointerProperties[pointerIndex].toolType);
Prabir Pradhand65552b2021-10-07 11:23:50 -0700548}
549
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800550// Determines if the given window can be targeted as InputTarget::Flags::FOREGROUND.
Prabir Pradhan6dfbf262022-03-14 15:24:30 +0000551// Foreground events are only sent to "foreground targetable" windows, but not all gestures sent to
552// such window are necessarily targeted with the flag. For example, an event with ACTION_OUTSIDE can
553// be sent to such a window, but it is not a foreground event and doesn't use
Siarhei Vishniakou253f4642022-11-09 13:42:06 -0800554// InputTarget::Flags::FOREGROUND.
Prabir Pradhan6dfbf262022-03-14 15:24:30 +0000555bool canReceiveForegroundTouches(const WindowInfo& info) {
556 // A non-touchable window can still receive touch events (e.g. in the case of
557 // STYLUS_INTERCEPTOR), so prevent such windows from receiving foreground events for touches.
558 return !info.inputConfig.test(gui::WindowInfo::InputConfig::NOT_TOUCHABLE) && !info.isSpy();
559}
560
Prabir Pradhanaeebeb42023-06-13 19:53:03 +0000561bool isWindowOwnedBy(const sp<WindowInfoHandle>& windowHandle, gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -0700562 if (windowHandle == nullptr) {
563 return false;
564 }
565 const WindowInfo* windowInfo = windowHandle->getInfo();
566 if (pid == windowInfo->ownerPid && uid == windowInfo->ownerUid) {
567 return true;
568 }
569 return false;
570}
571
Prabir Pradhan5735a322022-04-11 17:23:34 +0000572// Checks targeted injection using the window's owner's uid.
573// Returns an empty string if an entry can be sent to the given window, or an error message if the
574// entry is a targeted injection whose uid target doesn't match the window owner.
575std::optional<std::string> verifyTargetedInjection(const sp<WindowInfoHandle>& window,
576 const EventEntry& entry) {
577 if (entry.injectionState == nullptr || !entry.injectionState->targetUid) {
578 // The event was not injected, or the injected event does not target a window.
579 return {};
580 }
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000581 const auto uid = *entry.injectionState->targetUid;
Prabir Pradhan5735a322022-04-11 17:23:34 +0000582 if (window == nullptr) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000583 return StringPrintf("No valid window target for injection into uid %s.",
584 uid.toString().c_str());
Prabir Pradhan5735a322022-04-11 17:23:34 +0000585 }
586 if (entry.injectionState->targetUid != window->getInfo()->ownerUid) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +0000587 return StringPrintf("Injected event targeted at uid %s would be dispatched to window '%s' "
588 "owned by uid %s.",
589 uid.toString().c_str(), window->getName().c_str(),
590 window->getInfo()->ownerUid.toString().c_str());
Prabir Pradhan5735a322022-04-11 17:23:34 +0000591 }
592 return {};
593}
594
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000595std::pair<float, float> resolveTouchedPosition(const MotionEntry& entry) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700596 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
597 // Always dispatch mouse events to cursor position.
598 if (isFromMouse) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000599 return {entry.xCursorPosition, entry.yCursorPosition};
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700600 }
601
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -0700602 const int32_t pointerIndex = MotionEvent::getActionIndex(entry.action);
Prabir Pradhan82e081e2022-12-06 09:50:09 +0000603 return {entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X),
604 entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y)};
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -0700605}
606
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -0700607std::optional<nsecs_t> getDownTime(const EventEntry& eventEntry) {
608 if (eventEntry.type == EventEntry::Type::KEY) {
609 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
610 return keyEntry.downTime;
611 } else if (eventEntry.type == EventEntry::Type::MOTION) {
612 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
613 return motionEntry.downTime;
614 }
615 return std::nullopt;
616}
617
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000618/**
619 * Compare the old touch state to the new touch state, and generate the corresponding touched
620 * windows (== input targets).
621 * If a window had the hovering pointer, but now it doesn't, produce HOVER_EXIT for that window.
622 * If the pointer just entered the new window, produce HOVER_ENTER.
623 * For pointers remaining in the window, produce HOVER_MOVE.
624 */
625std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState,
626 const TouchState& newTouchState,
627 const MotionEntry& entry) {
628 std::vector<TouchedWindow> out;
629 const int32_t maskedAction = MotionEvent::getActionMasked(entry.action);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -0700630
631 if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
632 // ACTION_SCROLL events should not affect the hovering pointer dispatch
633 return {};
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000634 }
635
636 // We should consider all hovering pointers here. But for now, just use the first one
637 const int32_t pointerId = entry.pointerProperties[0].id;
638
639 std::set<sp<WindowInfoHandle>> oldWindows;
640 if (oldState != nullptr) {
641 oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId);
642 }
643
644 std::set<sp<WindowInfoHandle>> newWindows =
645 newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointerId);
646
647 // If the pointer is no longer in the new window set, send HOVER_EXIT.
648 for (const sp<WindowInfoHandle>& oldWindow : oldWindows) {
649 if (newWindows.find(oldWindow) == newWindows.end()) {
650 TouchedWindow touchedWindow;
651 touchedWindow.windowHandle = oldWindow;
652 touchedWindow.targetFlags = InputTarget::Flags::DISPATCH_AS_HOVER_EXIT;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000653 out.push_back(touchedWindow);
654 }
655 }
656
657 for (const sp<WindowInfoHandle>& newWindow : newWindows) {
658 TouchedWindow touchedWindow;
659 touchedWindow.windowHandle = newWindow;
660 if (oldWindows.find(newWindow) == oldWindows.end()) {
661 // Any windows that have this pointer now, and didn't have it before, should get
662 // HOVER_ENTER
663 touchedWindow.targetFlags = InputTarget::Flags::DISPATCH_AS_HOVER_ENTER;
664 } else {
665 // This pointer was already sent to the window. Use ACTION_HOVER_MOVE.
Siarhei Vishniakouc2eb8502023-04-11 18:33:36 -0700666 if (CC_UNLIKELY(maskedAction != AMOTION_EVENT_ACTION_HOVER_MOVE)) {
Daniel Norman7487dfa2023-08-02 16:39:45 -0700667 android::base::LogSeverity severity = android::base::LogSeverity::FATAL;
Ameer Armalycff4fa52023-10-04 23:45:11 +0000668 if (!input_flags::a11y_crash_on_inconsistent_event_stream() &&
669 entry.flags & AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT) {
Daniel Norman7487dfa2023-08-02 16:39:45 -0700670 // The Accessibility injected touch exploration event stream
671 // has known inconsistencies, so log ERROR instead of
672 // crashing the device with FATAL.
Daniel Norman7487dfa2023-08-02 16:39:45 -0700673 severity = android::base::LogSeverity::ERROR;
674 }
675 LOG(severity) << "Expected ACTION_HOVER_MOVE instead of " << entry.getDescription();
Siarhei Vishniakouc2eb8502023-04-11 18:33:36 -0700676 }
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000677 touchedWindow.targetFlags = InputTarget::Flags::DISPATCH_AS_IS;
678 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700679 touchedWindow.addHoveringPointer(entry.deviceId, pointerId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000680 if (canReceiveForegroundTouches(*newWindow->getInfo())) {
681 touchedWindow.targetFlags |= InputTarget::Flags::FOREGROUND;
682 }
683 out.push_back(touchedWindow);
684 }
685 return out;
686}
687
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -0800688template <typename T>
689std::vector<T>& operator+=(std::vector<T>& left, const std::vector<T>& right) {
690 left.insert(left.end(), right.begin(), right.end());
691 return left;
692}
693
Harry Cuttsb166c002023-05-09 13:06:05 +0000694// Filter windows in a TouchState and targets in a vector to remove untrusted windows/targets from
695// both.
696void filterUntrustedTargets(TouchState& touchState, std::vector<InputTarget>& targets) {
697 std::erase_if(touchState.windows, [&](const TouchedWindow& window) {
698 if (!window.windowHandle->getInfo()->inputConfig.test(
699 WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
700 // In addition to TouchState, erase this window from the input targets! We don't have a
701 // good way to do this today except by adding a nested loop.
702 // TODO(b/282025641): simplify this code once InputTargets are being identified
703 // separately from TouchedWindows.
704 std::erase_if(targets, [&](const InputTarget& target) {
705 return target.inputChannel->getConnectionToken() == window.windowHandle->getToken();
706 });
707 return true;
708 }
709 return false;
710 });
711}
712
Siarhei Vishniakouce1fd472023-09-18 18:38:07 -0700713/**
714 * In general, touch should be always split between windows. Some exceptions:
715 * 1. Don't split touch if all of the below is true:
716 * (a) we have an active pointer down *and*
717 * (b) a new pointer is going down that's from the same device *and*
718 * (c) the window that's receiving the current pointer does not support split touch.
719 * 2. Don't split mouse events
720 */
721bool shouldSplitTouch(const TouchState& touchState, const MotionEntry& entry) {
722 if (isFromSource(entry.source, AINPUT_SOURCE_MOUSE)) {
723 // We should never split mouse events
724 return false;
725 }
726 for (const TouchedWindow& touchedWindow : touchState.windows) {
727 if (touchedWindow.windowHandle->getInfo()->isSpy()) {
728 // Spy windows should not affect whether or not touch is split.
729 continue;
730 }
731 if (touchedWindow.windowHandle->getInfo()->supportsSplitTouch()) {
732 continue;
733 }
734 if (touchedWindow.windowHandle->getInfo()->inputConfig.test(
735 gui::WindowInfo::InputConfig::IS_WALLPAPER)) {
736 // Wallpaper window should not affect whether or not touch is split
737 continue;
738 }
739
740 if (touchedWindow.hasTouchingPointers(entry.deviceId)) {
741 return false;
742 }
743 }
744 return true;
745}
746
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000747} // namespace
748
Michael Wrightd02c5b62014-02-10 15:10:22 -0800749// --- InputDispatcher ---
750
Prabir Pradhana41d2442023-04-20 21:30:40 +0000751InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy)
Garfield Tan00f511d2019-06-12 16:55:40 -0700752 : mPolicy(policy),
753 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700754 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800755 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700756 mAppSwitchSawKeyDown(false),
Colin Cross5b799302022-10-18 21:52:41 -0700757 mAppSwitchDueTime(LLONG_MAX),
Garfield Tan00f511d2019-06-12 16:55:40 -0700758 mNextUnblockedEvent(nullptr),
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800759 mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
Garfield Tan00f511d2019-06-12 16:55:40 -0700760 mDispatchEnabled(false),
761 mDispatchFrozen(false),
762 mInputFilterEnabled(false),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100763 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000764 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800765 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000766 mLatencyAggregator(),
Antonio Kantek15beb512022-06-13 22:35:41 +0000767 mLatencyTracker(&mLatencyAggregator) {
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700768 mLooper = sp<Looper>::make(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800769 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800770
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700771 mWindowInfoListener = sp<DispatcherWindowListener>::make(*this);
Siarhei Vishniakou31977182022-09-30 08:51:23 -0700772#if defined(__ANDROID__)
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700773 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
Siarhei Vishniakou31977182022-09-30 08:51:23 -0700774#endif
Yi Kong9b14ac62018-07-17 13:48:38 -0700775 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800776}
777
778InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000779 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800780
Prabir Pradhancef936d2021-07-21 16:17:52 +0000781 resetKeyRepeatLocked();
782 releasePendingEventLocked();
783 drainInboundQueueLocked();
784 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800785
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000786 while (!mConnectionsByToken.empty()) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -0700787 std::shared_ptr<Connection> connection = mConnectionsByToken.begin()->second;
Harry Cutts33476232023-01-30 19:57:29 +0000788 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), /*notify=*/false);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800789 }
790}
791
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700792status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700793 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700794 return ALREADY_EXISTS;
795 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700796 mThread = std::make_unique<InputThread>(
797 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
798 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700799}
800
801status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700802 if (mThread && mThread->isCallingThread()) {
803 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700804 return INVALID_OPERATION;
805 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700806 mThread.reset();
807 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700808}
809
Michael Wrightd02c5b62014-02-10 15:10:22 -0800810void InputDispatcher::dispatchOnce() {
Colin Cross5b799302022-10-18 21:52:41 -0700811 nsecs_t nextWakeupTime = LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800812 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800813 std::scoped_lock _l(mLock);
814 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800815
816 // Run a dispatch loop if there are no pending commands.
817 // The dispatch loop might enqueue commands to run afterwards.
818 if (!haveCommandsLocked()) {
819 dispatchOnceInnerLocked(&nextWakeupTime);
820 }
821
822 // Run all pending commands if there are any.
823 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000824 if (runCommandsLockedInterruptable()) {
Colin Cross5b799302022-10-18 21:52:41 -0700825 nextWakeupTime = LLONG_MIN;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800826 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800827
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700828 // If we are still waiting for ack on some events,
829 // we might have to wake up earlier to check if an app is anr'ing.
830 const nsecs_t nextAnrCheck = processAnrsLocked();
831 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
832
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800833 // We are about to enter an infinitely long sleep, because we have no commands or
834 // pending or queued events
Colin Cross5b799302022-10-18 21:52:41 -0700835 if (nextWakeupTime == LLONG_MAX) {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800836 mDispatcherEnteredIdle.notify_all();
837 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800838 } // release lock
839
840 // Wait for callback or timeout or wake. (make sure we round up, not down)
841 nsecs_t currentTime = now();
842 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
843 mLooper->pollOnce(timeoutMillis);
844}
845
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700846/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500847 * Raise ANR if there is no focused window.
848 * Before the ANR is raised, do a final state check:
849 * 1. The currently focused application must be the same one we are waiting for.
850 * 2. Ensure we still don't have a focused window.
851 */
852void InputDispatcher::processNoFocusedWindowAnrLocked() {
853 // Check if the application that we are waiting for is still focused.
854 std::shared_ptr<InputApplicationHandle> focusedApplication =
855 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
856 if (focusedApplication == nullptr ||
857 focusedApplication->getApplicationToken() !=
858 mAwaitedFocusedApplication->getApplicationToken()) {
859 // Unexpected because we should have reset the ANR timer when focused application changed
860 ALOGE("Waited for a focused window, but focused application has already changed to %s",
861 focusedApplication->getName().c_str());
862 return; // The focused application has changed.
863 }
864
chaviw98318de2021-05-19 16:45:23 -0500865 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500866 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
867 if (focusedWindowHandle != nullptr) {
868 return; // We now have a focused window. No need for ANR.
869 }
870 onAnrLocked(mAwaitedFocusedApplication);
871}
872
873/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700874 * Check if any of the connections' wait queues have events that are too old.
875 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
876 * Return the time at which we should wake up next.
877 */
878nsecs_t InputDispatcher::processAnrsLocked() {
879 const nsecs_t currentTime = now();
Colin Cross5b799302022-10-18 21:52:41 -0700880 nsecs_t nextAnrCheck = LLONG_MAX;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700881 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
882 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
883 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500884 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700885 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500886 mNoFocusedWindowTimeoutTime = std::nullopt;
Colin Cross5b799302022-10-18 21:52:41 -0700887 return LLONG_MIN;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700888 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500889 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700890 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
891 }
892 }
893
894 // Check if any connection ANRs are due
895 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
896 if (currentTime < nextAnrCheck) { // most likely scenario
897 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
898 }
899
900 // If we reached here, we have an unresponsive connection.
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -0700901 std::shared_ptr<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700902 if (connection == nullptr) {
903 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
904 return nextAnrCheck;
905 }
906 connection->responsive = false;
907 // Stop waking up for this unresponsive connection
908 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000909 onAnrLocked(connection);
Colin Cross5b799302022-10-18 21:52:41 -0700910 return LLONG_MIN;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700911}
912
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800913std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -0700914 const std::shared_ptr<Connection>& connection) {
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800915 if (connection->monitor) {
916 return mMonitorDispatchingTimeout;
917 }
918 const sp<WindowInfoHandle> window =
919 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700920 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500921 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700922 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500923 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700924}
925
Michael Wrightd02c5b62014-02-10 15:10:22 -0800926void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
927 nsecs_t currentTime = now();
928
Jeff Browndc5992e2014-04-11 01:27:26 -0700929 // Reset the key repeat timer whenever normal dispatch is suspended while the
930 // device is in a non-interactive state. This is to ensure that we abort a key
931 // repeat if the device is just coming out of sleep.
932 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800933 resetKeyRepeatLocked();
934 }
935
936 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
937 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100938 if (DEBUG_FOCUS) {
939 ALOGD("Dispatch frozen. Waiting some more.");
940 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800941 return;
942 }
943
944 // Optimize latency of app switches.
945 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
946 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
Siarhei Vishniakou6520a582023-10-27 21:53:45 -0700947 bool isAppSwitchDue;
Siarhei Vishniakou17f12282023-11-02 13:40:29 -0700948 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -0700949 isAppSwitchDue = mAppSwitchDueTime <= currentTime;
950 if (mAppSwitchDueTime < *nextWakeupTime) {
951 *nextWakeupTime = mAppSwitchDueTime;
952 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800953 }
954
955 // Ready to start a new event.
956 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700957 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700958 if (mInboundQueue.empty()) {
Siarhei Vishniakou17f12282023-11-02 13:40:29 -0700959 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -0700960 if (isAppSwitchDue) {
961 // The inbound queue is empty so the app switch key we were waiting
962 // for will never arrive. Stop waiting for it.
963 resetPendingAppSwitchLocked(false);
964 isAppSwitchDue = false;
965 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800966 }
967
968 // Synthesize a key repeat if appropriate.
969 if (mKeyRepeatState.lastKeyEntry) {
970 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
971 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
972 } else {
973 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
974 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
975 }
976 }
977 }
978
979 // Nothing to do if there is no pending event.
980 if (!mPendingEvent) {
981 return;
982 }
983 } else {
984 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700985 mPendingEvent = mInboundQueue.front();
986 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800987 traceInboundQueueLengthLocked();
988 }
989
990 // Poke user activity for this event.
991 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700992 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800993 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800994 }
995
996 // Now we have an event to dispatch.
997 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700998 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800999 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001000 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001001 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001002 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001003 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001004 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001005 }
1006
1007 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001008 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001009 }
1010
1011 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001012 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001013 const ConfigurationChangedEntry& typedEntry =
1014 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001015 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001016 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001017 break;
1018 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001019
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001020 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001021 const DeviceResetEntry& typedEntry =
1022 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001023 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001024 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001025 break;
1026 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001027
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001028 case EventEntry::Type::FOCUS: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001029 std::shared_ptr<const FocusEntry> typedEntry =
1030 std::static_pointer_cast<const FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001031 dispatchFocusLocked(currentTime, typedEntry);
1032 done = true;
1033 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
1034 break;
1035 }
1036
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001037 case EventEntry::Type::TOUCH_MODE_CHANGED: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001038 const auto typedEntry = std::static_pointer_cast<const TouchModeEntry>(mPendingEvent);
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001039 dispatchTouchModeChangeLocked(currentTime, typedEntry);
1040 done = true;
1041 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
1042 break;
1043 }
1044
Prabir Pradhan99987712020-11-10 18:43:05 -08001045 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1046 const auto typedEntry =
Prabir Pradhan24047542023-11-02 17:14:59 +00001047 std::static_pointer_cast<const PointerCaptureChangedEntry>(mPendingEvent);
Prabir Pradhan99987712020-11-10 18:43:05 -08001048 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
1049 done = true;
1050 break;
1051 }
1052
arthurhungb89ccb02020-12-30 16:19:01 +08001053 case EventEntry::Type::DRAG: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001054 std::shared_ptr<const DragEntry> typedEntry =
1055 std::static_pointer_cast<const DragEntry>(mPendingEvent);
arthurhungb89ccb02020-12-30 16:19:01 +08001056 dispatchDragLocked(currentTime, typedEntry);
1057 done = true;
1058 break;
1059 }
1060
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001061 case EventEntry::Type::KEY: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001062 std::shared_ptr<const KeyEntry> keyEntry =
1063 std::static_pointer_cast<const KeyEntry>(mPendingEvent);
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001064 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001065 if (isAppSwitchDue) {
1066 if (isAppSwitchKeyEvent(*keyEntry)) {
1067 resetPendingAppSwitchLocked(true);
1068 isAppSwitchDue = false;
1069 } else if (dropReason == DropReason::NOT_DROPPED) {
1070 dropReason = DropReason::APP_SWITCH;
1071 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001072 }
1073 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001074 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001075 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001076 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001077 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
1078 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001079 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001080 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001081 break;
1082 }
1083
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001084 case EventEntry::Type::MOTION: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001085 std::shared_ptr<const MotionEntry> motionEntry =
1086 std::static_pointer_cast<const MotionEntry>(mPendingEvent);
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001087 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001088 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
1089 dropReason = DropReason::APP_SWITCH;
1090 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001091 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001092 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001093 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001094 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001095 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
1096 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001097 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001098 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001099 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001100 }
Chris Yef59a2f42020-10-16 12:55:26 -07001101
1102 case EventEntry::Type::SENSOR: {
Prabir Pradhan24047542023-11-02 17:14:59 +00001103 std::shared_ptr<const SensorEntry> sensorEntry =
1104 std::static_pointer_cast<const SensorEntry>(mPendingEvent);
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001105 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001106 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
1107 dropReason = DropReason::APP_SWITCH;
1108 }
Chris Yef59a2f42020-10-16 12:55:26 -07001109 }
1110 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
1111 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
1112 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
1113 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
1114 dropReason = DropReason::STALE;
1115 }
1116 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
1117 done = true;
1118 break;
1119 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001120 }
1121
1122 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001123 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001124 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001125 }
Michael Wright3a981722015-06-10 15:26:13 +01001126 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001127
1128 releasePendingEventLocked();
Colin Cross5b799302022-10-18 21:52:41 -07001129 *nextWakeupTime = LLONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130 }
1131}
1132
Siarhei Vishniakou289e9242022-02-15 14:50:16 -08001133bool InputDispatcher::isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
Siarhei Vishniakoua7333112023-10-27 13:33:29 -07001134 return mPolicy.isStaleEvent(currentTime, entry.eventTime);
Siarhei Vishniakou289e9242022-02-15 14:50:16 -08001135}
1136
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001137/**
1138 * Return true if the events preceding this incoming motion event should be dropped
1139 * Return false otherwise (the default behaviour)
1140 */
1141bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001142 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001143 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001144
1145 // Optimize case where the current application is unresponsive and the user
1146 // decides to touch a window in a different application.
1147 // If the application takes too long to catch up then we drop all events preceding
1148 // the touch into the other window.
1149 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07001150 const int32_t displayId = motionEntry.displayId;
1151 const auto [x, y] = resolveTouchedPosition(motionEntry);
Harry Cutts33476232023-01-30 19:57:29 +00001152 const bool isStylus = isPointerFromStylus(motionEntry, /*pointerIndex=*/0);
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07001153
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001154 sp<WindowInfoHandle> touchedWindowHandle =
1155 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001156 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001157 touchedWindowHandle->getApplicationToken() !=
1158 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001159 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001160 ALOGI("Pruning input queue because user touched a different application while waiting "
1161 "for %s",
1162 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001163 return true;
1164 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001165
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001166 // Alternatively, maybe there's a spy window that could handle this event.
1167 const std::vector<sp<WindowInfoHandle>> touchedSpies =
1168 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
1169 for (const auto& windowHandle : touchedSpies) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07001170 const std::shared_ptr<Connection> connection =
1171 getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +00001172 if (connection != nullptr && connection->responsive) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001173 // This spy window could take more input. Drop all events preceding this
1174 // event, so that the spy window can get a chance to receive the stream.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001175 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001176 "responsive spy window that may handle the event.",
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001177 mAwaitedFocusedApplication->getName().c_str());
1178 return true;
1179 }
1180 }
1181 }
1182
1183 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
1184 // yet been processed by some connections, the dispatcher will wait for these motion
1185 // events to be processed before dispatching the key event. This is because these motion events
1186 // may cause a new window to be launched, which the user might expect to receive focus.
1187 // To prevent waiting forever for such events, just send the key to the currently focused window
1188 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
1189 ALOGD("Received a new pointer down event, stop waiting for events to process and "
1190 "just send the pending key event to the focused window.");
1191 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001192 }
1193 return false;
1194}
1195
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001196bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001197 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001198 mInboundQueue.push_back(std::move(newEntry));
Prabir Pradhan24047542023-11-02 17:14:59 +00001199 const EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001200 traceInboundQueueLengthLocked();
1201
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001202 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001203 case EventEntry::Type::KEY: {
Prabir Pradhan5735a322022-04-11 17:23:34 +00001204 LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1205 "Unexpected untrusted event.");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001206 // Optimize app switch latency.
1207 // If the application takes too long to catch up then we drop all events preceding
1208 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001209 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001210
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07001211 if (!REMOVE_APP_SWITCH_DROPS) {
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07001212 if (isAppSwitchKeyEvent(keyEntry)) {
1213 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
1214 mAppSwitchSawKeyDown = true;
1215 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
1216 if (mAppSwitchSawKeyDown) {
1217 if (DEBUG_APP_SWITCH) {
1218 ALOGD("App switch is pending!");
1219 }
1220 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
1221 mAppSwitchSawKeyDown = false;
1222 needWake = true;
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001223 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001224 }
1225 }
1226 }
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001227 // If a new up event comes in, and the pending event with same key code has been asked
1228 // to try again later because of the policy. We have to reset the intercept key wake up
1229 // time for it may have been handled in the policy and could be dropped.
1230 if (keyEntry.action == AKEY_EVENT_ACTION_UP && mPendingEvent &&
1231 mPendingEvent->type == EventEntry::Type::KEY) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001232 const KeyEntry& pendingKey = static_cast<const KeyEntry&>(*mPendingEvent);
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001233 if (pendingKey.keyCode == keyEntry.keyCode &&
1234 pendingKey.interceptKeyResult ==
Michael Wright5caf55a2022-11-24 22:31:42 +00001235 KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
1236 pendingKey.interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001237 pendingKey.interceptKeyWakeupTime = 0;
1238 needWake = true;
1239 }
1240 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001241 break;
1242 }
1243
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001244 case EventEntry::Type::MOTION: {
Prabir Pradhan5735a322022-04-11 17:23:34 +00001245 LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1246 "Unexpected untrusted event.");
Prabir Pradhan24047542023-11-02 17:14:59 +00001247 if (shouldPruneInboundQueueLocked(static_cast<const MotionEntry&>(entry))) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001248 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001249 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001250 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001251 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001252 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001253 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001254 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1255 break;
1256 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001257 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001258 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001259 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001260 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001261 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1262 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001263 // nothing to do
1264 break;
1265 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001266 }
1267
1268 return needWake;
1269}
1270
Prabir Pradhan24047542023-11-02 17:14:59 +00001271void InputDispatcher::addRecentEventLocked(std::shared_ptr<const EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001272 // Do not store sensor event in recent queue to avoid flooding the queue.
1273 if (entry->type != EventEntry::Type::SENSOR) {
1274 mRecentQueue.push_back(entry);
1275 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001276 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001277 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001278 }
1279}
1280
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001281sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, float x, float y,
1282 bool isStylus,
1283 bool ignoreDragWindow) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001284 // Traverse windows from front to back to find touched window.
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001285 const auto& windowHandles = getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05001286 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001287 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001288 continue;
1289 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001290
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001291 const WindowInfo& info = *windowHandle->getInfo();
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00001292 if (!info.isSpy() &&
1293 windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001294 return windowHandle;
1295 }
1296 }
1297 return nullptr;
1298}
1299
1300std::vector<InputTarget> InputDispatcher::findOutsideTargetsLocked(
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07001301 int32_t displayId, const sp<WindowInfoHandle>& touchedWindow, int32_t pointerId) const {
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001302 if (touchedWindow == nullptr) {
1303 return {};
1304 }
1305 // Traverse windows from front to back until we encounter the touched window.
1306 std::vector<InputTarget> outsideTargets;
1307 const auto& windowHandles = getWindowHandlesLocked(displayId);
1308 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1309 if (windowHandle == touchedWindow) {
1310 // Stop iterating once we found a touched window. Any WATCH_OUTSIDE_TOUCH window
1311 // below the touched window will not get ACTION_OUTSIDE event.
1312 return outsideTargets;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001313 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001314
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001315 const WindowInfo& info = *windowHandle->getInfo();
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08001316 if (info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07001317 std::bitset<MAX_POINTER_ID + 1> pointerIds;
1318 pointerIds.set(pointerId);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07001319 addPointerWindowTargetLocked(windowHandle, InputTarget::Flags::DISPATCH_AS_OUTSIDE,
1320 pointerIds,
1321 /*firstDownTimeInTarget=*/std::nullopt, outsideTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001322 }
1323 }
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07001324 return outsideTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001325}
1326
Prabir Pradhand65552b2021-10-07 11:23:50 -07001327std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
Prabir Pradhan82e081e2022-12-06 09:50:09 +00001328 int32_t displayId, float x, float y, bool isStylus) const {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001329 // Traverse windows from front to back and gather the touched spy windows.
1330 std::vector<sp<WindowInfoHandle>> spyWindows;
1331 const auto& windowHandles = getWindowHandlesLocked(displayId);
1332 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1333 const WindowInfo& info = *windowHandle->getInfo();
1334
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00001335 if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001336 continue;
1337 }
1338 if (!info.isSpy()) {
1339 // The first touched non-spy window was found, so return the spy windows touched so far.
1340 return spyWindows;
1341 }
1342 spyWindows.push_back(windowHandle);
1343 }
1344 return spyWindows;
1345}
1346
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001347void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001348 const char* reason;
1349 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001350 case DropReason::POLICY:
Prabir Pradhan65613802023-02-22 23:36:58 +00001351 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001352 ALOGD("Dropped event because policy consumed it.");
1353 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001354 reason = "inbound event was dropped because the policy consumed it";
1355 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001356 case DropReason::DISABLED:
1357 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001358 ALOGI("Dropped event because input dispatch is disabled.");
1359 }
1360 reason = "inbound event was dropped because input dispatch is disabled";
1361 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001362 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001363 ALOGI("Dropped event because of pending overdue app switch.");
1364 reason = "inbound event was dropped because of pending overdue app switch";
1365 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001366 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001367 ALOGI("Dropped event because the current application is not responding and the user "
1368 "has started interacting with a different application.");
1369 reason = "inbound event was dropped because the current application is not responding "
1370 "and the user has started interacting with a different application";
1371 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001372 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001373 ALOGI("Dropped event because it is stale.");
1374 reason = "inbound event was dropped because it is stale";
1375 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001376 case DropReason::NO_POINTER_CAPTURE:
1377 ALOGI("Dropped event because there is no window with Pointer Capture.");
1378 reason = "inbound event was dropped because there is no window with Pointer Capture";
1379 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001380 case DropReason::NOT_DROPPED: {
1381 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001382 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001383 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001384 }
1385
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001386 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001387 case EventEntry::Type::KEY: {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001388 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001389 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001390 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001391 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001392 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001393 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1394 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001395 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, reason);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001396 synthesizeCancelationEventsForAllConnectionsLocked(options);
1397 } else {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001398 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
1399 reason);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001400 synthesizeCancelationEventsForAllConnectionsLocked(options);
1401 }
1402 break;
1403 }
Chris Yef59a2f42020-10-16 12:55:26 -07001404 case EventEntry::Type::SENSOR: {
1405 break;
1406 }
arthurhungb89ccb02020-12-30 16:19:01 +08001407 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1408 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001409 break;
1410 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001411 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001412 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001413 case EventEntry::Type::CONFIGURATION_CHANGED:
1414 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001415 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001416 break;
1417 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001418 }
1419}
1420
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001421static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001422 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1423 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001424}
1425
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001426bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1427 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1428 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1429 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001430}
1431
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07001432bool InputDispatcher::isAppSwitchPendingLocked() const {
Colin Cross5b799302022-10-18 21:52:41 -07001433 return mAppSwitchDueTime != LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001434}
1435
1436void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
Colin Cross5b799302022-10-18 21:52:41 -07001437 mAppSwitchDueTime = LLONG_MAX;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001438
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001439 if (DEBUG_APP_SWITCH) {
1440 if (handled) {
1441 ALOGD("App switch has arrived.");
1442 } else {
1443 ALOGD("App switch was abandoned.");
1444 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001445 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001446}
1447
Michael Wrightd02c5b62014-02-10 15:10:22 -08001448bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001449 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001450}
1451
Prabir Pradhancef936d2021-07-21 16:17:52 +00001452bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001453 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001454 return false;
1455 }
1456
1457 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001458 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001459 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001460 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1461 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001462 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001463 return true;
1464}
1465
Prabir Pradhancef936d2021-07-21 16:17:52 +00001466void InputDispatcher::postCommandLocked(Command&& command) {
1467 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001468}
1469
1470void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001471 while (!mInboundQueue.empty()) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001472 std::shared_ptr<const EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001473 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001474 releaseInboundEventLocked(entry);
1475 }
1476 traceInboundQueueLengthLocked();
1477}
1478
1479void InputDispatcher::releasePendingEventLocked() {
1480 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001481 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001482 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001483 }
1484}
1485
Prabir Pradhan24047542023-11-02 17:14:59 +00001486void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<const EventEntry> entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00001487 const std::shared_ptr<InjectionState>& injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001488 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001489 if (DEBUG_DISPATCH_CYCLE) {
1490 ALOGD("Injected inbound event was dropped.");
1491 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001492 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001493 }
1494 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001495 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001496 }
1497 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001498}
1499
1500void InputDispatcher::resetKeyRepeatLocked() {
1501 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001502 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001503 }
1504}
1505
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001506std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001507 std::shared_ptr<const KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001508
Michael Wright2e732952014-09-24 13:26:59 -07001509 uint32_t policyFlags = entry->policyFlags &
1510 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001511
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001512 std::shared_ptr<KeyEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00001513 std::make_unique<KeyEntry>(mIdGenerator.nextId(), /*injectionState=*/nullptr,
1514 currentTime, entry->deviceId, entry->source,
1515 entry->displayId, policyFlags, entry->action, entry->flags,
1516 entry->keyCode, entry->scanCode, entry->metaState,
1517 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001518
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001519 newEntry->syntheticRepeat = true;
1520 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001521 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001522 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001523}
1524
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001525bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001526 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001527 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1528 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1529 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001530
1531 // Reset key repeating in case a keyboard device was added or removed or something.
1532 resetKeyRepeatLocked();
1533
1534 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001535 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1536 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00001537 mPolicy.notifyConfigurationChanged(eventTime);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001538 };
1539 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001540 return true;
1541}
1542
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001543bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1544 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001545 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1546 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1547 entry.deviceId);
1548 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001549
liushenxiang42232912021-05-21 20:24:09 +08001550 // Reset key repeating in case a keyboard device was disabled or enabled.
1551 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1552 resetKeyRepeatLocked();
1553 }
1554
Michael Wrightfb04fd52022-11-24 22:31:11 +00001555 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001556 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001557 synthesizeCancelationEventsForAllConnectionsLocked(options);
Siarhei Vishniakou0686f0c2023-05-02 11:56:15 -07001558
1559 // Remove all active pointers from this device
1560 for (auto& [_, touchState] : mTouchStatesByDisplay) {
1561 touchState.removeAllPointersForDevice(entry.deviceId);
1562 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001563 return true;
1564}
1565
Vishnu Nairad321cd2020-08-20 16:40:21 -07001566void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001567 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001568 if (mPendingEvent != nullptr) {
1569 // Move the pending event to the front of the queue. This will give the chance
1570 // for the pending event to get dispatched to the newly focused window
1571 mInboundQueue.push_front(mPendingEvent);
1572 mPendingEvent = nullptr;
1573 }
1574
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001575 std::unique_ptr<FocusEntry> focusEntry =
1576 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1577 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001578
1579 // This event should go to the front of the queue, but behind all other focus events
1580 // Find the last focus event, and insert right after it
Prabir Pradhan24047542023-11-02 17:14:59 +00001581 auto it = std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
1582 [](const std::shared_ptr<const EventEntry>& event) {
1583 return event->type == EventEntry::Type::FOCUS;
1584 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001585
1586 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001587 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001588}
1589
Prabir Pradhan24047542023-11-02 17:14:59 +00001590void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime,
1591 std::shared_ptr<const FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001592 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001593 if (channel == nullptr) {
1594 return; // Window has gone away
1595 }
1596 InputTarget target;
1597 target.inputChannel = channel;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001598 target.flags = InputTarget::Flags::DISPATCH_AS_IS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001599 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001600 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1601 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001602 std::string reason = std::string("reason=").append(entry->reason);
1603 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001604 dispatchEventLocked(currentTime, entry, {target});
1605}
1606
Prabir Pradhan99987712020-11-10 18:43:05 -08001607void InputDispatcher::dispatchPointerCaptureChangedLocked(
Prabir Pradhan24047542023-11-02 17:14:59 +00001608 nsecs_t currentTime, const std::shared_ptr<const PointerCaptureChangedEntry>& entry,
Prabir Pradhan99987712020-11-10 18:43:05 -08001609 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001610 dropReason = DropReason::NOT_DROPPED;
1611
Prabir Pradhan99987712020-11-10 18:43:05 -08001612 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001613 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001614
1615 if (entry->pointerCaptureRequest.enable) {
1616 // Enable Pointer Capture.
1617 if (haveWindowWithPointerCapture &&
1618 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
Prabir Pradhan7092e262022-05-03 16:51:09 +00001619 // This can happen if pointer capture is disabled and re-enabled before we notify the
1620 // app of the state change, so there is no need to notify the app.
1621 ALOGI("Skipping dispatch of Pointer Capture being enabled: no state change.");
1622 return;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001623 }
1624 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001625 // This can happen if a window requests capture and immediately releases capture.
1626 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001627 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001628 return;
1629 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001630 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1631 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1632 return;
1633 }
1634
Vishnu Nairc519ff72021-01-21 08:23:08 -08001635 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001636 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1637 mWindowTokenWithPointerCapture = token;
1638 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001639 // Disable Pointer Capture.
1640 // We do not check if the sequence number matches for requests to disable Pointer Capture
1641 // for two reasons:
1642 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1643 // to disable capture with the same sequence number: one generated by
1644 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1645 // Capture being disabled in InputReader.
1646 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1647 // actual Pointer Capture state that affects events being generated by input devices is
1648 // in InputReader.
1649 if (!haveWindowWithPointerCapture) {
1650 // Pointer capture was already forcefully disabled because of focus change.
1651 dropReason = DropReason::NOT_DROPPED;
1652 return;
1653 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001654 token = mWindowTokenWithPointerCapture;
1655 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001656 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001657 setPointerCaptureLocked(false);
1658 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001659 }
1660
1661 auto channel = getInputChannelLocked(token);
1662 if (channel == nullptr) {
1663 // Window has gone away, clean up Pointer Capture state.
1664 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001665 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001666 setPointerCaptureLocked(false);
1667 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001668 return;
1669 }
1670 InputTarget target;
1671 target.inputChannel = channel;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001672 target.flags = InputTarget::Flags::DISPATCH_AS_IS;
Prabir Pradhan99987712020-11-10 18:43:05 -08001673 entry->dispatchInProgress = true;
1674 dispatchEventLocked(currentTime, entry, {target});
1675
1676 dropReason = DropReason::NOT_DROPPED;
1677}
1678
Prabir Pradhan24047542023-11-02 17:14:59 +00001679void InputDispatcher::dispatchTouchModeChangeLocked(
1680 nsecs_t currentTime, const std::shared_ptr<const TouchModeEntry>& entry) {
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001681 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Antonio Kantek15beb512022-06-13 22:35:41 +00001682 getWindowHandlesLocked(entry->displayId);
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001683 if (windowHandles.empty()) {
1684 return;
1685 }
1686 const std::vector<InputTarget> inputTargets =
1687 getInputTargetsFromWindowHandlesLocked(windowHandles);
1688 if (inputTargets.empty()) {
1689 return;
1690 }
1691 entry->dispatchInProgress = true;
1692 dispatchEventLocked(currentTime, entry, inputTargets);
1693}
1694
1695std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1696 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1697 std::vector<InputTarget> inputTargets;
1698 for (const sp<WindowInfoHandle>& handle : windowHandles) {
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001699 const sp<IBinder>& token = handle->getToken();
1700 if (token == nullptr) {
1701 continue;
1702 }
1703 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1704 if (channel == nullptr) {
1705 continue; // Window has gone away
1706 }
1707 InputTarget target;
1708 target.inputChannel = channel;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001709 target.flags = InputTarget::Flags::DISPATCH_AS_IS;
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001710 inputTargets.push_back(target);
1711 }
1712 return inputTargets;
1713}
1714
Prabir Pradhan24047542023-11-02 17:14:59 +00001715bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001716 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001717 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001718 if (!entry->dispatchInProgress) {
1719 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1720 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1721 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1722 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001723 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001724 // We have seen two identical key downs in a row which indicates that the device
1725 // driver is automatically generating key repeats itself. We take note of the
1726 // repeat here, but we disable our own next key repeat timer since it is clear that
1727 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001728 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1729 // Make sure we don't get key down from a different device. If a different
1730 // device Id has same key pressed down, the new device Id will replace the
1731 // current one to hold the key repeat with repeat count reset.
1732 // In the future when got a KEY_UP on the device id, drop it and do not
1733 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001734 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1735 resetKeyRepeatLocked();
Colin Cross5b799302022-10-18 21:52:41 -07001736 mKeyRepeatState.nextRepeatTime = LLONG_MAX; // don't generate repeats ourselves
Michael Wrightd02c5b62014-02-10 15:10:22 -08001737 } else {
1738 // Not a repeat. Save key down state in case we do see a repeat later.
1739 resetKeyRepeatLocked();
1740 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1741 }
1742 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001743 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1744 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001745 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan65613802023-02-22 23:36:58 +00001746 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001747 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1748 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001749 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001750 resetKeyRepeatLocked();
1751 }
1752
1753 if (entry->repeatCount == 1) {
1754 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1755 } else {
1756 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1757 }
1758
1759 entry->dispatchInProgress = true;
1760
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001761 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001762 }
1763
1764 // Handle case where the policy asked us to try again later last time.
Michael Wright5caf55a2022-11-24 22:31:42 +00001765 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001766 if (currentTime < entry->interceptKeyWakeupTime) {
1767 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1768 *nextWakeupTime = entry->interceptKeyWakeupTime;
1769 }
1770 return false; // wait until next wakeup
1771 }
Michael Wright5caf55a2022-11-24 22:31:42 +00001772 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001773 entry->interceptKeyWakeupTime = 0;
1774 }
1775
1776 // Give the policy a chance to intercept the key.
Michael Wright5caf55a2022-11-24 22:31:42 +00001777 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001778 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001779 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001780 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001781
1782 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1783 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1784 };
1785 postCommandLocked(std::move(command));
Josep del Riob3981622023-04-18 15:49:45 +00001786 // Poke user activity for keys not passed to user
1787 pokeUserActivityLocked(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001788 return false; // wait for the command to run
1789 } else {
Michael Wright5caf55a2022-11-24 22:31:42 +00001790 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001791 }
Michael Wright5caf55a2022-11-24 22:31:42 +00001792 } else if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001793 if (*dropReason == DropReason::NOT_DROPPED) {
1794 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001795 }
1796 }
1797
1798 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001799 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001800 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001801 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1802 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001803 mReporter->reportDroppedKey(entry->id);
Josep del Riob3981622023-04-18 15:49:45 +00001804 // Poke user activity for undispatched keys
1805 pokeUserActivityLocked(*entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001806 return true;
1807 }
1808
1809 // Identify targets.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001810 InputEventInjectionResult injectionResult;
1811 sp<WindowInfoHandle> focusedWindow =
1812 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime,
1813 /*byref*/ injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001814 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001815 return false;
1816 }
1817
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001818 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001819 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001820 return true;
1821 }
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001822 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
1823
1824 std::vector<InputTarget> inputTargets;
1825 addWindowTargetLocked(focusedWindow,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001826 InputTarget::Flags::FOREGROUND | InputTarget::Flags::DISPATCH_AS_IS,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07001827 getDownTime(*entry), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001828
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001829 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001830 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001831
1832 // Dispatch the key.
1833 dispatchEventLocked(currentTime, entry, inputTargets);
1834 return true;
1835}
1836
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001837void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001838 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1839 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1840 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1841 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1842 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1843 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1844 entry.metaState, entry.repeatCount, entry.downTime);
1845 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001846}
1847
Prabir Pradhancef936d2021-07-21 16:17:52 +00001848void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
Prabir Pradhan24047542023-11-02 17:14:59 +00001849 const std::shared_ptr<const SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001850 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001851 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1852 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1853 "source=0x%x, sensorType=%s",
1854 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001855 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001856 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001857 auto command = [this, entry]() REQUIRES(mLock) {
1858 scoped_unlock unlock(mLock);
1859
1860 if (entry->accuracyChanged) {
Prabir Pradhana41d2442023-04-20 21:30:40 +00001861 mPolicy.notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001862 }
Prabir Pradhana41d2442023-04-20 21:30:40 +00001863 mPolicy.notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1864 entry->hwTimestamp, entry->values);
Prabir Pradhancef936d2021-07-21 16:17:52 +00001865 };
1866 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001867}
1868
1869bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001870 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1871 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001872 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001873 }
Chris Yef59a2f42020-10-16 12:55:26 -07001874 { // acquire lock
1875 std::scoped_lock _l(mLock);
1876
1877 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
Prabir Pradhan24047542023-11-02 17:14:59 +00001878 std::shared_ptr<const EventEntry> entry = *it;
Chris Yef59a2f42020-10-16 12:55:26 -07001879 if (entry->type == EventEntry::Type::SENSOR) {
1880 it = mInboundQueue.erase(it);
1881 releaseInboundEventLocked(entry);
1882 }
1883 }
1884 }
1885 return true;
1886}
1887
Prabir Pradhan24047542023-11-02 17:14:59 +00001888bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime,
1889 std::shared_ptr<const MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001890 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001891 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001892 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001893 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001894 entry->dispatchInProgress = true;
1895
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001896 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001897 }
1898
1899 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001900 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001901 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001902 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1903 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001904 return true;
1905 }
1906
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001907 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001908
1909 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001910 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001911
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001912 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001913 if (isPointerEvent) {
1914 // Pointer event. (eg. touchscreen)
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00001915
1916 if (mDragState &&
1917 (entry->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN) {
1918 // If drag and drop ongoing and pointer down occur: pilfer drag window pointers
1919 pilferPointersLocked(mDragState->dragWindow->getToken());
1920 }
1921
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08001922 inputTargets =
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07001923 findTouchedWindowTargetsLocked(currentTime, *entry, /*byref*/ injectionResult);
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08001924 LOG_ALWAYS_FATAL_IF(injectionResult != InputEventInjectionResult::SUCCEEDED &&
1925 !inputTargets.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001926 } else {
1927 // Non touch event. (eg. trackball)
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001928 sp<WindowInfoHandle> focusedWindow =
1929 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime, injectionResult);
1930 if (injectionResult == InputEventInjectionResult::SUCCEEDED) {
1931 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
1932 addWindowTargetLocked(focusedWindow,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001933 InputTarget::Flags::FOREGROUND |
1934 InputTarget::Flags::DISPATCH_AS_IS,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07001935 getDownTime(*entry), inputTargets);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07001936 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001937 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001938 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001939 return false;
1940 }
1941
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001942 setInjectionResult(*entry, injectionResult);
Prabir Pradhan5735a322022-04-11 17:23:34 +00001943 if (injectionResult == InputEventInjectionResult::TARGET_MISMATCH) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001944 return true;
1945 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001946 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00001947 CancelationOptions::Mode mode(
1948 isPointerEvent ? CancelationOptions::Mode::CANCEL_POINTER_EVENTS
1949 : CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS);
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001950 CancelationOptions options(mode, "input event injection failed");
1951 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001952 return true;
1953 }
1954
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001955 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001956 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001957
1958 // Dispatch the motion.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001959 dispatchEventLocked(currentTime, entry, inputTargets);
1960 return true;
1961}
1962
chaviw98318de2021-05-19 16:45:23 -05001963void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
Arthur Hung54745652022-04-20 07:17:41 +00001964 bool isExiting, const int32_t rawX,
1965 const int32_t rawY) {
1966 const vec2 xy = windowHandle->getInfo()->transform.transform(vec2(rawX, rawY));
arthurhungb89ccb02020-12-30 16:19:01 +08001967 std::unique_ptr<DragEntry> dragEntry =
Arthur Hung54745652022-04-20 07:17:41 +00001968 std::make_unique<DragEntry>(mIdGenerator.nextId(), now(), windowHandle->getToken(),
1969 isExiting, xy.x, xy.y);
arthurhungb89ccb02020-12-30 16:19:01 +08001970
1971 enqueueInboundEventLocked(std::move(dragEntry));
1972}
1973
Prabir Pradhan24047542023-11-02 17:14:59 +00001974void InputDispatcher::dispatchDragLocked(nsecs_t currentTime,
1975 std::shared_ptr<const DragEntry> entry) {
arthurhungb89ccb02020-12-30 16:19:01 +08001976 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1977 if (channel == nullptr) {
1978 return; // Window has gone away
1979 }
1980 InputTarget target;
1981 target.inputChannel = channel;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08001982 target.flags = InputTarget::Flags::DISPATCH_AS_IS;
arthurhungb89ccb02020-12-30 16:19:01 +08001983 entry->dispatchInProgress = true;
1984 dispatchEventLocked(currentTime, entry, {target});
1985}
1986
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001987void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001988 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08001989 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=%s, displayId=%" PRId32
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001990 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001991 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001992 "metaState=0x%x, buttonState=0x%x,"
1993 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08001994 prefix, entry.eventTime, entry.deviceId,
1995 inputEventSourceToString(entry.source).c_str(), entry.displayId, entry.policyFlags,
1996 MotionEvent::actionToString(entry.action).c_str(), entry.actionButton, entry.flags,
1997 entry.metaState, entry.buttonState, entry.edgeFlags, entry.xPrecision,
1998 entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001999
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002000 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
Siarhei Vishniakou09a8fe42022-07-21 17:27:03 -07002001 ALOGD(" Pointer %d: id=%d, toolType=%s, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002002 "x=%f, y=%f, pressure=%f, size=%f, "
2003 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2004 "orientation=%f",
Siarhei Vishniakou09a8fe42022-07-21 17:27:03 -07002005 i, entry.pointerProperties[i].id,
2006 ftl::enum_string(entry.pointerProperties[i].toolType).c_str(),
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002007 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2008 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2009 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2010 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2011 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2012 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2013 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2014 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2015 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2016 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002017 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002018}
2019
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002020void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
Prabir Pradhan24047542023-11-02 17:14:59 +00002021 std::shared_ptr<const EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002022 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002023 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002024 if (DEBUG_DISPATCH_CYCLE) {
2025 ALOGD("dispatchEventToCurrentInputTargets");
2026 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002027
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00002028 processInteractionsLocked(*eventEntry, inputTargets);
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002029
Michael Wrightd02c5b62014-02-10 15:10:22 -08002030 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
2031
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002032 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002033
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002034 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002035 std::shared_ptr<Connection> connection =
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07002036 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002037 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002038 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002039 } else {
Siarhei Vishniakou31dd1552023-10-30 18:46:10 -07002040 if (DEBUG_DROPPED_EVENTS_VERBOSE) {
2041 LOG(INFO) << "Dropping event delivery to target with channel "
2042 << inputTarget.inputChannel->getName()
2043 << " because it is no longer registered with the input dispatcher.";
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002044 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002045 }
2046 }
2047}
2048
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002049void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002050 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
2051 // If the policy decides to close the app, we will get a channel removal event via
2052 // unregisterInputChannel, and will clean up the connection that way. We are already not
2053 // sending new pointers to the connection when it blocked, but focused events will continue to
2054 // pile up.
2055 ALOGW("Canceling events for %s because it is unresponsive",
2056 connection->inputChannel->getName().c_str());
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002057 if (connection->status == Connection::Status::NORMAL) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00002058 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002059 "application not responding");
2060 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002061 }
2062}
2063
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002064void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002065 if (DEBUG_FOCUS) {
2066 ALOGD("Resetting ANR timeouts.");
2067 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002068
2069 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002070 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07002071 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002072}
2073
Tiger Huang721e26f2018-07-24 22:26:19 +08002074/**
2075 * Get the display id that the given event should go to. If this event specifies a valid display id,
2076 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
2077 * Focused display is the display that the user most recently interacted with.
2078 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002079int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08002080 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002081 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002082 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002083 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2084 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002085 break;
2086 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002087 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002088 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2089 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002090 break;
2091 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002092 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002093 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002094 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002095 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07002096 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08002097 case EventEntry::Type::SENSOR:
2098 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08002099 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002100 return ADISPLAY_ID_NONE;
2101 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002102 }
2103 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
2104}
2105
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002106bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
2107 const char* focusedWindowName) {
2108 if (mAnrTracker.empty()) {
2109 // already processed all events that we waited for
2110 mKeyIsWaitingForEventsTimeout = std::nullopt;
2111 return false;
2112 }
2113
2114 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
2115 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00002116 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002117 mKeyIsWaitingForEventsTimeout = currentTime +
2118 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
2119 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002120 return true;
2121 }
2122
2123 // We still have pending events, and already started the timer
2124 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
2125 return true; // Still waiting
2126 }
2127
2128 // Waited too long, and some connection still hasn't processed all motions
2129 // Just send the key to the focused window
2130 ALOGW("Dispatching key to %s even though there are other unprocessed events",
2131 focusedWindowName);
2132 mKeyIsWaitingForEventsTimeout = std::nullopt;
2133 return false;
2134}
2135
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002136sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked(
2137 nsecs_t currentTime, const EventEntry& entry, nsecs_t* nextWakeupTime,
2138 InputEventInjectionResult& outInjectionResult) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002139 std::string reason;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002140 outInjectionResult = InputEventInjectionResult::FAILED; // Default result
Michael Wrightd02c5b62014-02-10 15:10:22 -08002141
Tiger Huang721e26f2018-07-24 22:26:19 +08002142 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05002143 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07002144 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08002145 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
2146
Michael Wrightd02c5b62014-02-10 15:10:22 -08002147 // If there is no currently focused window and no focused application
2148 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002149 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
2150 ALOGI("Dropping %s event because there is no focused window or focused application in "
2151 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08002152 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002153 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002154 }
2155
Vishnu Nair062a8672021-09-03 16:07:44 -07002156 // Drop key events if requested by input feature
2157 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002158 return nullptr;
Vishnu Nair062a8672021-09-03 16:07:44 -07002159 }
2160
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002161 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
2162 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
2163 // start interacting with another application via touch (app switch). This code can be removed
2164 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
2165 // an app is expected to have a focused window.
2166 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
2167 if (!mNoFocusedWindowTimeoutTime.has_value()) {
2168 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05002169 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
2170 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
2171 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002172 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05002173 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002174 ALOGW("Waiting because no window has focus but %s may eventually add a "
2175 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05002176 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002177 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002178 outInjectionResult = InputEventInjectionResult::PENDING;
2179 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002180 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
2181 // Already raised ANR. Drop the event
2182 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08002183 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002184 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002185 } else {
2186 // Still waiting for the focused window
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002187 outInjectionResult = InputEventInjectionResult::PENDING;
2188 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002189 }
2190 }
2191
2192 // we have a valid, non-null focused window
2193 resetNoFocusedWindowTimeoutLocked();
2194
Prabir Pradhan5735a322022-04-11 17:23:34 +00002195 // Verify targeted injection.
2196 if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) {
2197 ALOGW("Dropping injected event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002198 outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
2199 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002200 }
2201
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002202 if (focusedWindowHandle->getInfo()->inputConfig.test(
2203 WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002204 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002205 outInjectionResult = InputEventInjectionResult::PENDING;
2206 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002207 }
2208
2209 // If the event is a key event, then we must wait for all previous events to
2210 // complete before delivering it because previous events may have the
2211 // side-effect of transferring focus to a different window and we want to
2212 // ensure that the following keys are sent to the new window.
2213 //
2214 // Suppose the user touches a button in a window then immediately presses "A".
2215 // If the button causes a pop-up window to appear then we want to ensure that
2216 // the "A" key is delivered to the new pop-up window. This is because users
2217 // often anticipate pending UI changes when typing on a keyboard.
2218 // To obtain this behavior, we must serialize key events with respect to all
2219 // prior input events.
2220 if (entry.type == EventEntry::Type::KEY) {
2221 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
2222 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002223 outInjectionResult = InputEventInjectionResult::PENDING;
2224 return nullptr;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002225 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002226 }
2227
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002228 outInjectionResult = InputEventInjectionResult::SUCCEEDED;
2229 return focusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002230}
2231
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002232/**
2233 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
2234 * that are currently unresponsive.
2235 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002236std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
2237 const std::vector<Monitor>& monitors) const {
2238 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002239 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002240 [this](const Monitor& monitor) REQUIRES(mLock) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07002241 std::shared_ptr<Connection> connection =
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002242 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002243 if (connection == nullptr) {
2244 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002245 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002246 return false;
2247 }
2248 if (!connection->responsive) {
2249 ALOGW("Unresponsive monitor %s will not get the new gesture",
2250 connection->inputChannel->getName().c_str());
2251 return false;
2252 }
2253 return true;
2254 });
2255 return responsiveMonitors;
2256}
2257
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002258std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002259 nsecs_t currentTime, const MotionEntry& entry,
Siarhei Vishniakou4fe57392022-10-25 13:44:30 -07002260 InputEventInjectionResult& outInjectionResult) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002261 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002262
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002263 std::vector<InputTarget> targets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002264 // For security reasons, we defer updating the touch state until we are sure that
2265 // event injection will be allowed.
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002266 const int32_t displayId = entry.displayId;
2267 const int32_t action = entry.action;
Siarhei Vishniakoubf880522023-05-01 11:03:22 -07002268 const int32_t maskedAction = MotionEvent::getActionMasked(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002269
2270 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002271 outInjectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002272
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002273 // Copy current touch state into tempTouchState.
2274 // This state will be used to update mTouchStatesByDisplay at the end of this function.
2275 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07002276 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002277 TouchState tempTouchState;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002278 if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
2279 oldState = &(it->second);
Prabir Pradhane680f9b2022-02-04 04:24:00 -08002280 tempTouchState = *oldState;
Jeff Brownf086ddb2014-02-11 14:28:48 -08002281 }
2282
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002283 bool isSplit = shouldSplitTouch(tempTouchState, entry);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002284
2285 const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2286 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2287 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002288 // A DOWN could be generated from POINTER_DOWN if the initial pointers did not land into any
2289 // touchable windows.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002290 const bool wasDown = oldState != nullptr && oldState->isDown(entry.deviceId);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002291 const bool isDown = (maskedAction == AMOTION_EVENT_ACTION_DOWN) ||
2292 (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN && !wasDown);
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002293 const bool newGesture = isDown || maskedAction == AMOTION_EVENT_ACTION_SCROLL ||
2294 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2295 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE;
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002296 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Siarhei Vishniakou5cee1e32022-11-29 12:35:39 -08002297
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002298 if (newGesture) {
2299 isSplit = false;
Siarhei Vishniakouf372b812023-02-14 18:06:51 -08002300 }
2301
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002302 if (isDown && tempTouchState.hasHoveringPointers(entry.deviceId)) {
2303 // Compatibility behaviour: ACTION_DOWN causes HOVER_EXIT to get generated.
2304 tempTouchState.clearHoveringPointers(entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002305 }
2306
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002307 if (isHoverAction) {
Siarhei Vishniakou7be50c92023-11-17 17:09:08 -08002308 if (wasDown) {
2309 // Started hovering, but the device is already down: reject the hover event
2310 LOG(ERROR) << "Got hover event " << entry.getDescription()
2311 << " but the device is already down " << oldState->dump();
2312 outInjectionResult = InputEventInjectionResult::FAILED;
2313 return {};
2314 }
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002315 // For hover actions, we will treat 'tempTouchState' as a new state, so let's erase
2316 // all of the existing hovering pointers and recompute.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002317 tempTouchState.clearHoveringPointers(entry.deviceId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002318 }
2319
Michael Wrightd02c5b62014-02-10 15:10:22 -08002320 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2321 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07002322 const auto [x, y] = resolveTouchedPosition(entry);
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002323 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07002324 const int32_t pointerId = entry.pointerProperties[pointerIndex].id;
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002325 // Outside targets should be added upon first dispatched DOWN event. That means, this should
2326 // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down.
Prabir Pradhand65552b2021-10-07 11:23:50 -07002327 const bool isStylus = isPointerFromStylus(entry, pointerIndex);
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002328 sp<WindowInfoHandle> newTouchedWindowHandle =
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002329 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Michael Wright3dd60e22019-03-27 22:06:44 +00002330
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002331 if (isDown) {
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07002332 targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointerId);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002333 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002334 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002335 if (newTouchedWindowHandle == nullptr) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00002336 ALOGD("No new touched window at (%.1f, %.1f) in display %" PRId32, x, y, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002337 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002338 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002339 }
2340
Prabir Pradhan5735a322022-04-11 17:23:34 +00002341 // Verify targeted injection.
2342 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2343 ALOGW("Dropping injected touch event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002344 outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
Prabir Pradhan5735a322022-04-11 17:23:34 +00002345 newTouchedWindowHandle = nullptr;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002346 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002347 }
2348
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002349 // Figure out whether splitting will be allowed for this window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002350 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002351 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2352 // New window supports splitting, but we should never split mouse events.
2353 isSplit = !isFromMouse;
2354 } else if (isSplit) {
2355 // New window does not support splitting but we have already split events.
2356 // Ignore the new window.
Siarhei Vishniakou25537f82023-07-18 14:35:47 -07002357 LOG(INFO) << "Skipping " << newTouchedWindowHandle->getName()
2358 << " because it doesn't support split touch";
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002359 newTouchedWindowHandle = nullptr;
2360 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002361 } else {
2362 // No window is touched, so set split to true. This will allow the next pointer down to
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002363 // be delivered to a new window which supports split touch. Pointers from a mouse device
2364 // should never be split.
Siarhei Vishniakou64a98532022-10-25 15:20:24 -07002365 isSplit = !isFromMouse;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002366 }
2367
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002368 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002369 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002370 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002371 // Process the foreground window first so that it is the first to receive the event.
2372 newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002373 }
2374
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002375 if (newTouchedWindows.empty()) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00002376 ALOGI("Dropping event because there is no touchable window at (%.1f, %.1f) on display "
2377 "%d.",
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002378 x, y, displayId);
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002379 outInjectionResult = InputEventInjectionResult::FAILED;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002380 return {};
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002381 }
2382
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002383 for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07002384 if (!canWindowReceiveMotionLocked(windowHandle, entry)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002385 continue;
2386 }
2387
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002388 if (isHoverAction) {
Siarhei Vishniakoub681c202023-05-01 11:22:33 -07002389 // The "windowHandle" is the target of this hovering pointer.
2390 tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointerId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002391 }
2392
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002393 // Set target flags.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002394 ftl::Flags<InputTarget::Flags> targetFlags = InputTarget::Flags::DISPATCH_AS_IS;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002395
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002396 if (canReceiveForegroundTouches(*windowHandle->getInfo())) {
2397 // There should only be one touched window that can be "foreground" for the pointer.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002398 targetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002399 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002400
2401 if (isSplit) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002402 targetFlags |= InputTarget::Flags::SPLIT;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002403 }
2404 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002405 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002406 } else if (isWindowObscuredLocked(windowHandle)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002407 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002408 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002409
2410 // Update the temporary touch state.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002411
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002412 if (!isHoverAction) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002413 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakou70f3d8c2023-09-19 15:36:52 -07002414 pointerIds.set(pointerId);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002415 const bool isDownOrPointerDown = maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2416 maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN;
2417 tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, entry.deviceId,
2418 pointerIds,
2419 isDownOrPointerDown
2420 ? std::make_optional(entry.eventTime)
2421 : std::nullopt);
2422 // If this is the pointer going down and the touched window has a wallpaper
2423 // then also add the touched wallpaper windows so they are locked in for the
2424 // duration of the touch gesture. We do not collect wallpapers during HOVER_MOVE or
2425 // SCROLL because the wallpaper engine only supports touch events. We would need to
2426 // add a mechanism similar to View.onGenericMotionEvent to enable wallpapers to
2427 // handle these events.
2428 if (isDownOrPointerDown && targetFlags.test(InputTarget::Flags::FOREGROUND) &&
Arthur Hungc539dbb2022-12-08 07:45:36 +00002429 windowHandle->getInfo()->inputConfig.test(
2430 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
2431 sp<WindowInfoHandle> wallpaper = findWallpaperWindowBelow(windowHandle);
2432 if (wallpaper != nullptr) {
2433 ftl::Flags<InputTarget::Flags> wallpaperFlags =
2434 InputTarget::Flags::WINDOW_IS_OBSCURED |
2435 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED |
2436 InputTarget::Flags::DISPATCH_AS_IS;
2437 if (isSplit) {
2438 wallpaperFlags |= InputTarget::Flags::SPLIT;
2439 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002440 tempTouchState.addOrUpdateWindow(wallpaper, wallpaperFlags, entry.deviceId,
2441 pointerIds, entry.eventTime);
Arthur Hungc539dbb2022-12-08 07:45:36 +00002442 }
2443 }
2444 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002445 }
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00002446
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002447 // If a window is already pilfering some pointers, give it this new pointer as well and
2448 // make it pilfering. This will prevent other non-spy windows from getting this pointer,
2449 // which is a specific behaviour that we want.
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002450 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002451 if (touchedWindow.hasTouchingPointer(entry.deviceId, pointerId) &&
2452 touchedWindow.hasPilferingPointers(entry.deviceId)) {
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002453 // This window is already pilfering some pointers, and this new pointer is also
2454 // going to it. Therefore, take over this pointer and don't give it to anyone
2455 // else.
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002456 touchedWindow.addPilferingPointer(entry.deviceId, pointerId);
Vaibhav Devmurariff798f32022-05-09 23:45:04 +00002457 }
2458 }
Siarhei Vishniakou060f82b2023-01-27 06:39:14 -08002459
2460 // Restrict all pilfered pointers to the pilfering windows.
2461 tempTouchState.cancelPointersForNonPilferingWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002462 } else {
2463 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2464
2465 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002466 if (!tempTouchState.isDown(entry.deviceId) &&
2467 maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) {
Siarhei Vishniakou31dd1552023-10-30 18:46:10 -07002468 if (DEBUG_DROPPED_EVENTS_VERBOSE) {
2469 LOG(INFO) << "Dropping event because the pointer for device " << entry.deviceId
2470 << " is not down or we previously dropped the pointer down event in "
2471 << "display " << displayId << ": " << entry.getDescription();
2472 }
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002473 outInjectionResult = InputEventInjectionResult::FAILED;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002474 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002475 }
2476
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002477 // If the pointer is not currently hovering, then ignore the event.
2478 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2479 const int32_t pointerId = entry.pointerProperties[0].id;
2480 if (oldState == nullptr ||
2481 oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId).empty()) {
2482 LOG(INFO) << "Dropping event because the hovering pointer is not in any windows in "
2483 "display "
2484 << displayId << ": " << entry.getDescription();
2485 outInjectionResult = InputEventInjectionResult::FAILED;
2486 return {};
2487 }
2488 tempTouchState.removeHoveringPointer(entry.deviceId, pointerId);
2489 }
2490
arthurhung6d4bed92021-03-17 11:59:33 +08002491 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002492
Michael Wrightd02c5b62014-02-10 15:10:22 -08002493 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002494 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.getPointerCount() == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002495 tempTouchState.isSlippery()) {
Siarhei Vishniakou9306c382022-09-30 15:30:31 -07002496 const auto [x, y] = resolveTouchedPosition(entry);
Harry Cutts33476232023-01-30 19:57:29 +00002497 const bool isStylus = isPointerFromStylus(entry, /*pointerIndex=*/0);
chaviw98318de2021-05-19 16:45:23 -05002498 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002499 tempTouchState.getFirstForegroundWindowHandle();
Siarhei Vishniakou0f6558d2023-04-21 12:05:13 -07002500 LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr);
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002501 sp<WindowInfoHandle> newTouchedWindowHandle =
2502 findTouchedWindowAtLocked(displayId, x, y, isStylus);
Vishnu Nair062a8672021-09-03 16:07:44 -07002503
Prabir Pradhan5735a322022-04-11 17:23:34 +00002504 // Verify targeted injection.
2505 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2506 ALOGW("Dropping injected event: %s", (*err).c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002507 outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002508 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002509 }
2510
Vishnu Nair062a8672021-09-03 16:07:44 -07002511 // Drop touch events if requested by input feature
2512 if (newTouchedWindowHandle != nullptr &&
2513 shouldDropInput(entry, newTouchedWindowHandle)) {
2514 newTouchedWindowHandle = nullptr;
2515 }
2516
Siarhei Vishniakouafa08cc2023-05-08 22:35:50 -07002517 if (newTouchedWindowHandle != nullptr &&
2518 !haveSameToken(oldTouchedWindowHandle, newTouchedWindowHandle)) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002519 ALOGI("Touch is slipping out of window %s into window %s in display %" PRId32,
Siarhei Vishniakou0f6558d2023-04-21 12:05:13 -07002520 oldTouchedWindowHandle->getName().c_str(),
2521 newTouchedWindowHandle->getName().c_str(), displayId);
2522
Michael Wrightd02c5b62014-02-10 15:10:22 -08002523 // Make a slippery exit from the old window.
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08002524 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002525 const int32_t pointerId = entry.pointerProperties[0].id;
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08002526 pointerIds.set(pointerId);
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002527
2528 const TouchedWindow& touchedWindow =
2529 tempTouchState.getTouchedWindow(oldTouchedWindowHandle);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002530 addPointerWindowTargetLocked(oldTouchedWindowHandle,
2531 InputTarget::Flags::DISPATCH_AS_SLIPPERY_EXIT,
2532 pointerIds,
2533 touchedWindow.getDownTimeInTarget(entry.deviceId),
2534 targets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002535
2536 // Make a slippery entrance into the new window.
2537 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002538 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002539 }
2540
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002541 ftl::Flags<InputTarget::Flags> targetFlags =
2542 InputTarget::Flags::DISPATCH_AS_SLIPPERY_ENTER;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002543 if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002544 targetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002545 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002546 if (isSplit) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002547 targetFlags |= InputTarget::Flags::SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002548 }
2549 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002550 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002551 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002552 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002553 }
2554
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002555 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags,
2556 entry.deviceId, pointerIds, entry.eventTime);
Arthur Hungc539dbb2022-12-08 07:45:36 +00002557
2558 // Check if the wallpaper window should deliver the corresponding event.
2559 slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002560 tempTouchState, entry.deviceId, pointerId, targets);
2561 tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointerId,
2562 oldTouchedWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002563 }
2564 }
Arthur Hung96483742022-11-15 03:30:48 +00002565
2566 // Update the pointerIds for non-splittable when it received pointer down.
2567 if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2568 // If no split, we suppose all touched windows should receive pointer down.
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002569 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
Arthur Hung96483742022-11-15 03:30:48 +00002570 for (size_t i = 0; i < tempTouchState.windows.size(); i++) {
2571 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2572 // Ignore drag window for it should just track one pointer.
2573 if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
2574 continue;
2575 }
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002576 std::bitset<MAX_POINTER_ID + 1> touchingPointers;
2577 touchingPointers.set(entry.pointerProperties[pointerIndex].id);
2578 touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers);
Arthur Hung96483742022-11-15 03:30:48 +00002579 }
2580 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002581 }
2582
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002583 // Update dispatching for hover enter and exit.
Sam Dubeyf886dec2023-01-27 13:28:19 +00002584 {
2585 std::vector<TouchedWindow> hoveringWindows =
2586 getHoveringWindowsLocked(oldState, tempTouchState, entry);
2587 for (const TouchedWindow& touchedWindow : hoveringWindows) {
Siarhei Vishniakoud5876ba2023-05-15 17:58:34 -07002588 std::optional<InputTarget> target =
2589 createInputTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002590 touchedWindow.getDownTimeInTarget(entry.deviceId));
Siarhei Vishniakoud5876ba2023-05-15 17:58:34 -07002591 if (!target) {
2592 continue;
2593 }
2594 // Hardcode to single hovering pointer for now.
2595 std::bitset<MAX_POINTER_ID + 1> pointerIds;
2596 pointerIds.set(entry.pointerProperties[0].id);
2597 target->addPointers(pointerIds, touchedWindow.windowHandle->getInfo()->transform);
2598 targets.push_back(*target);
Sam Dubeyf886dec2023-01-27 13:28:19 +00002599 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002600 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002601
Prabir Pradhan5735a322022-04-11 17:23:34 +00002602 // Ensure that all touched windows are valid for injection.
2603 if (entry.injectionState != nullptr) {
2604 std::string errs;
2605 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Prabir Pradhan5735a322022-04-11 17:23:34 +00002606 const auto err = verifyTargetedInjection(touchedWindow.windowHandle, entry);
2607 if (err) errs += "\n - " + *err;
2608 }
2609 if (!errs.empty()) {
2610 ALOGW("Dropping targeted injection: At least one touched window is not owned by uid "
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00002611 "%s:%s",
2612 entry.injectionState->targetUid->toString().c_str(), errs.c_str());
Siarhei Vishniakou6278ca22022-10-25 11:19:19 -07002613 outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
Siarhei Vishniakou8619eb32022-12-01 21:30:59 -08002614 return {};
Prabir Pradhan5735a322022-04-11 17:23:34 +00002615 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002616 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002617
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002618 // Check whether windows listening for outside touches are owned by the same UID. If the owner
2619 // has a different UID, then we will not reveal coordinate information to this window.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002620 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002621 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002622 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002623 if (foregroundWindowHandle) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00002624 const auto foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002625 for (InputTarget& target : targets) {
2626 if (target.flags.test(InputTarget::Flags::DISPATCH_AS_OUTSIDE)) {
2627 sp<WindowInfoHandle> targetWindow =
2628 getWindowHandleLocked(target.inputChannel->getConnectionToken());
2629 if (targetWindow->getInfo()->ownerUid != foregroundWindowUid) {
2630 target.flags |= InputTarget::Flags::ZERO_COORDS;
Michael Wright3dd60e22019-03-27 22:06:44 +00002631 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002632 }
2633 }
2634 }
2635 }
2636
Harry Cuttsb166c002023-05-09 13:06:05 +00002637 // If this is a touchpad navigation gesture, it needs to only be sent to trusted targets, as we
2638 // only want the system UI to handle these gestures.
2639 const bool isTouchpadNavGesture = isFromSource(entry.source, AINPUT_SOURCE_MOUSE) &&
2640 entry.classification == MotionClassification::MULTI_FINGER_SWIPE;
2641 if (isTouchpadNavGesture) {
2642 filterUntrustedTargets(/* byref */ tempTouchState, /* byref */ targets);
2643 }
2644
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002645 // Output targets from the touch state.
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002646 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002647 std::bitset<MAX_POINTER_ID + 1> touchingPointers =
2648 touchedWindow.getTouchingPointers(entry.deviceId);
2649 if (touchingPointers.none()) {
Siarhei Vishniakoue0431e42023-01-28 17:01:39 -08002650 continue;
2651 }
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002652 addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
2653 touchingPointers,
2654 touchedWindow.getDownTimeInTarget(entry.deviceId), targets);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002655 }
Sam Dubey39d37cf2022-12-07 18:05:35 +00002656
Siarhei Vishniakou580fb3a2023-05-05 15:02:20 -07002657 // During targeted injection, only allow owned targets to receive events
2658 std::erase_if(targets, [&](const InputTarget& target) {
2659 LOG_ALWAYS_FATAL_IF(target.windowHandle == nullptr);
2660 const auto err = verifyTargetedInjection(target.windowHandle, entry);
2661 if (err) {
2662 LOG(WARNING) << "Dropping injected event from " << target.windowHandle->getName()
2663 << ": " << (*err);
2664 return true;
2665 }
2666 return false;
2667 });
2668
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07002669 if (targets.empty()) {
2670 LOG(INFO) << "Dropping event because no targets were found: " << entry.getDescription();
2671 outInjectionResult = InputEventInjectionResult::FAILED;
2672 return {};
2673 }
2674
2675 // If we only have windows getting ACTION_OUTSIDE, then drop the event, because there is no
2676 // window that is actually receiving the entire gesture.
2677 if (std::all_of(targets.begin(), targets.end(), [](const InputTarget& target) {
2678 return target.flags.test(InputTarget::Flags::DISPATCH_AS_OUTSIDE);
2679 })) {
2680 LOG(INFO) << "Dropping event because all windows would just receive ACTION_OUTSIDE: "
2681 << entry.getDescription();
2682 outInjectionResult = InputEventInjectionResult::FAILED;
2683 return {};
2684 }
2685
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002686 outInjectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002687
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002688 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
2689 // Targets that we entered in a slippery way will now become AS-IS targets
2690 if (touchedWindow.targetFlags.test(InputTarget::Flags::DISPATCH_AS_SLIPPERY_ENTER)) {
2691 touchedWindow.targetFlags.clear(InputTarget::Flags::DISPATCH_AS_SLIPPERY_ENTER);
2692 touchedWindow.targetFlags |= InputTarget::Flags::DISPATCH_AS_IS;
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002693 }
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002694 }
2695
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002696 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou7be50c92023-11-17 17:09:08 -08002697 if (maskedAction == AMOTION_EVENT_ACTION_UP) {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002698 // Pointer went up.
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07002699 tempTouchState.removeTouchingPointer(entry.deviceId, entry.pointerProperties[0].id);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +00002700 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002701 // All pointers up or canceled.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002702 tempTouchState.removeAllPointersForDevice(entry.deviceId);
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002703 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2704 // One pointer went up.
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002705 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
2706 const uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
2707 tempTouchState.removeTouchingPointer(entry.deviceId, pointerId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002708 }
2709
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002710 // Save changes unless the action was scroll in which case the temporary touch
2711 // state was only valid for this one action.
2712 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07002713 if (displayId >= 0) {
Siarhei Vishniakouf372b812023-02-14 18:06:51 -08002714 tempTouchState.clearWindowsWithoutPointers();
Siarhei Vishniakou79c32662022-10-25 17:56:25 -07002715 mTouchStatesByDisplay[displayId] = tempTouchState;
2716 } else {
2717 mTouchStatesByDisplay.erase(displayId);
2718 }
2719 }
2720
Siarhei Vishniakou0b0374d2022-11-17 17:40:53 -08002721 if (tempTouchState.windows.empty()) {
2722 mTouchStatesByDisplay.erase(displayId);
2723 }
2724
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08002725 return targets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002726}
2727
arthurhung6d4bed92021-03-17 11:59:33 +08002728void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07002729 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2730 // have an explicit reason to support it.
2731 constexpr bool isStylus = false;
2732
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002733 sp<WindowInfoHandle> dropWindow =
Harry Cutts33476232023-01-30 19:57:29 +00002734 findTouchedWindowAtLocked(displayId, x, y, isStylus, /*ignoreDragWindow=*/true);
arthurhung6d4bed92021-03-17 11:59:33 +08002735 if (dropWindow) {
2736 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002737 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002738 } else {
Arthur Hung54745652022-04-20 07:17:41 +00002739 ALOGW("No window found when drop.");
Prabir Pradhancef936d2021-07-21 16:17:52 +00002740 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002741 }
2742 mDragState.reset();
2743}
2744
2745void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
Arthur Hung3915c1f2022-05-31 07:17:17 +00002746 if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId) {
arthurhungb89ccb02020-12-30 16:19:01 +08002747 return;
2748 }
2749
arthurhung6d4bed92021-03-17 11:59:33 +08002750 if (!mDragState->isStartDrag) {
2751 mDragState->isStartDrag = true;
2752 mDragState->isStylusButtonDownAtStart =
2753 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2754 }
2755
Arthur Hung54745652022-04-20 07:17:41 +00002756 // Find the pointer index by id.
2757 int32_t pointerIndex = 0;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002758 for (; static_cast<uint32_t>(pointerIndex) < entry.getPointerCount(); pointerIndex++) {
Arthur Hung54745652022-04-20 07:17:41 +00002759 const PointerProperties& pointerProperties = entry.pointerProperties[pointerIndex];
2760 if (pointerProperties.id == mDragState->pointerId) {
2761 break;
arthurhung6d4bed92021-03-17 11:59:33 +08002762 }
Arthur Hung54745652022-04-20 07:17:41 +00002763 }
arthurhung6d4bed92021-03-17 11:59:33 +08002764
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07002765 if (uint32_t(pointerIndex) == entry.getPointerCount()) {
Arthur Hung54745652022-04-20 07:17:41 +00002766 LOG_ALWAYS_FATAL("Should find a valid pointer index by id %d", mDragState->pointerId);
Arthur Hung54745652022-04-20 07:17:41 +00002767 }
2768
2769 const int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2770 const int32_t x = entry.pointerCoords[pointerIndex].getX();
2771 const int32_t y = entry.pointerCoords[pointerIndex].getY();
2772
2773 switch (maskedAction) {
2774 case AMOTION_EVENT_ACTION_MOVE: {
2775 // Handle the special case : stylus button no longer pressed.
2776 bool isStylusButtonDown =
2777 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2778 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2779 finishDragAndDrop(entry.displayId, x, y);
2780 return;
2781 }
2782
2783 // Prevent stylus interceptor windows from affecting drag and drop behavior for now,
2784 // until we have an explicit reason to support it.
2785 constexpr bool isStylus = false;
2786
Siarhei Vishniakoue1ada272022-11-03 10:47:08 -07002787 sp<WindowInfoHandle> hoverWindowHandle =
2788 findTouchedWindowAtLocked(entry.displayId, x, y, isStylus,
2789 /*ignoreDragWindow=*/true);
Arthur Hung54745652022-04-20 07:17:41 +00002790 // enqueue drag exit if needed.
2791 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2792 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2793 if (mDragState->dragHoverWindowHandle != nullptr) {
Harry Cutts33476232023-01-30 19:57:29 +00002794 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, /*isExiting=*/true, x,
Arthur Hung54745652022-04-20 07:17:41 +00002795 y);
2796 }
2797 mDragState->dragHoverWindowHandle = hoverWindowHandle;
2798 }
2799 // enqueue drag location if needed.
2800 if (hoverWindowHandle != nullptr) {
Harry Cutts33476232023-01-30 19:57:29 +00002801 enqueueDragEventLocked(hoverWindowHandle, /*isExiting=*/false, x, y);
Arthur Hung54745652022-04-20 07:17:41 +00002802 }
2803 break;
2804 }
2805
2806 case AMOTION_EVENT_ACTION_POINTER_UP:
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07002807 if (MotionEvent::getActionIndex(entry.action) != pointerIndex) {
Arthur Hung54745652022-04-20 07:17:41 +00002808 break;
2809 }
2810 // The drag pointer is up.
2811 [[fallthrough]];
2812 case AMOTION_EVENT_ACTION_UP:
2813 finishDragAndDrop(entry.displayId, x, y);
2814 break;
2815 case AMOTION_EVENT_ACTION_CANCEL: {
2816 ALOGD("Receiving cancel when drag and drop.");
2817 sendDropWindowCommandLocked(nullptr, 0, 0);
2818 mDragState.reset();
2819 break;
2820 }
arthurhungb89ccb02020-12-30 16:19:01 +08002821 }
2822}
2823
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002824std::optional<InputTarget> InputDispatcher::createInputTargetLocked(
2825 const sp<android::gui::WindowInfoHandle>& windowHandle,
2826 ftl::Flags<InputTarget::Flags> targetFlags,
2827 std::optional<nsecs_t> firstDownTimeInTarget) const {
2828 std::shared_ptr<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
2829 if (inputChannel == nullptr) {
2830 ALOGW("Not creating InputTarget for %s, no input channel", windowHandle->getName().c_str());
2831 return {};
2832 }
2833 InputTarget inputTarget;
2834 inputTarget.inputChannel = inputChannel;
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00002835 inputTarget.windowHandle = windowHandle;
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002836 inputTarget.flags = targetFlags;
2837 inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor;
2838 inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
2839 const auto& displayInfoIt = mDisplayInfos.find(windowHandle->getInfo()->displayId);
2840 if (displayInfoIt != mDisplayInfos.end()) {
2841 inputTarget.displayTransform = displayInfoIt->second.transform;
2842 } else {
Siarhei Vishniakou580fb3a2023-05-05 15:02:20 -07002843 // DisplayInfo not found for this window on display windowHandle->getInfo()->displayId.
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002844 // TODO(b/198444055): Make this an error message after 'setInputWindows' API is removed.
2845 }
2846 return inputTarget;
2847}
2848
chaviw98318de2021-05-19 16:45:23 -05002849void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002850 ftl::Flags<InputTarget::Flags> targetFlags,
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002851 std::optional<nsecs_t> firstDownTimeInTarget,
Siarhei Vishniakouf75cddb2022-10-25 10:42:16 -07002852 std::vector<InputTarget>& inputTargets) const {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002853 std::vector<InputTarget>::iterator it =
2854 std::find_if(inputTargets.begin(), inputTargets.end(),
2855 [&windowHandle](const InputTarget& inputTarget) {
2856 return inputTarget.inputChannel->getConnectionToken() ==
2857 windowHandle->getToken();
2858 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002859
chaviw98318de2021-05-19 16:45:23 -05002860 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002861
2862 if (it == inputTargets.end()) {
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002863 std::optional<InputTarget> target =
2864 createInputTargetLocked(windowHandle, targetFlags, firstDownTimeInTarget);
2865 if (!target) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002866 return;
2867 }
Siarhei Vishniakou6c377b32023-05-15 17:03:39 -07002868 inputTargets.push_back(*target);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002869 it = inputTargets.end() - 1;
2870 }
2871
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002872 if (it->flags != targetFlags) {
2873 LOG(ERROR) << "Flags don't match! targetFlags=" << targetFlags.string() << ", it=" << *it;
2874 }
2875 if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
2876 LOG(ERROR) << "Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
2877 << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
2878 }
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07002879}
2880
2881void InputDispatcher::addPointerWindowTargetLocked(
2882 const sp<android::gui::WindowInfoHandle>& windowHandle,
2883 ftl::Flags<InputTarget::Flags> targetFlags, std::bitset<MAX_POINTER_ID + 1> pointerIds,
2884 std::optional<nsecs_t> firstDownTimeInTarget, std::vector<InputTarget>& inputTargets) const
2885 REQUIRES(mLock) {
2886 if (pointerIds.none()) {
2887 for (const auto& target : inputTargets) {
2888 LOG(INFO) << "Target: " << target;
2889 }
2890 LOG(FATAL) << "No pointers specified for " << windowHandle->getName();
2891 return;
2892 }
2893 std::vector<InputTarget>::iterator it =
2894 std::find_if(inputTargets.begin(), inputTargets.end(),
2895 [&windowHandle](const InputTarget& inputTarget) {
2896 return inputTarget.inputChannel->getConnectionToken() ==
2897 windowHandle->getToken();
2898 });
2899
2900 // This is a hack, because the actual entry could potentially be an ACTION_DOWN event that
2901 // causes a HOVER_EXIT to be generated. That means that the same entry of ACTION_DOWN would
2902 // have DISPATCH_AS_HOVER_EXIT and DISPATCH_AS_IS. And therefore, we have to create separate
2903 // input targets for hovering pointers and for touching pointers.
2904 // If we picked an existing input target above, but it's for HOVER_EXIT - let's use a new
2905 // target instead.
2906 if (it != inputTargets.end() && it->flags.test(InputTarget::Flags::DISPATCH_AS_HOVER_EXIT)) {
2907 // Force the code below to create a new input target
2908 it = inputTargets.end();
2909 }
2910
2911 const WindowInfo* windowInfo = windowHandle->getInfo();
2912
2913 if (it == inputTargets.end()) {
2914 std::optional<InputTarget> target =
2915 createInputTargetLocked(windowHandle, targetFlags, firstDownTimeInTarget);
2916 if (!target) {
2917 return;
2918 }
2919 inputTargets.push_back(*target);
2920 it = inputTargets.end() - 1;
2921 }
2922
Siarhei Vishniakou4bd0b7c2023-10-27 00:51:14 -07002923 if (it->flags != targetFlags) {
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002924 LOG(ERROR) << "Flags don't match! targetFlags=" << targetFlags.string() << ", it=" << *it;
Siarhei Vishniakou4bd0b7c2023-10-27 00:51:14 -07002925 }
Siarhei Vishniakou23d73fb2023-10-29 13:27:46 -07002926 if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
2927 LOG(ERROR) << "Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
2928 << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
2929 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002930
chaviw1ff3d1e2020-07-01 15:53:47 -07002931 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002932}
2933
Michael Wright3dd60e22019-03-27 22:06:44 +00002934void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002935 int32_t displayId) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002936 auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
2937 if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
Michael Wright3dd60e22019-03-27 22:06:44 +00002938
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002939 for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
2940 InputTarget target;
2941 target.inputChannel = monitor.inputChannel;
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002942 target.flags = InputTarget::Flags::DISPATCH_AS_IS;
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00002943 // target.firstDownTimeInTarget is not set for global monitors. It is only required in split
2944 // touch and global monitoring works as intended even without setting firstDownTimeInTarget
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002945 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
2946 target.displayTransform = it->second.transform;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002947 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002948 target.setDefaultPointerTransform(target.displayTransform);
2949 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002950 }
2951}
2952
Robert Carrc9bf1d32020-04-13 17:21:08 -07002953/**
2954 * Indicate whether one window handle should be considered as obscuring
2955 * another window handle. We only check a few preconditions. Actually
2956 * checking the bounds is left to the caller.
2957 */
chaviw98318de2021-05-19 16:45:23 -05002958static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2959 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002960 // Compare by token so cloned layers aren't counted
2961 if (haveSameToken(windowHandle, otherHandle)) {
2962 return false;
2963 }
2964 auto info = windowHandle->getInfo();
2965 auto otherInfo = otherHandle->getInfo();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002966 if (otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002967 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002968 } else if (otherInfo->alpha == 0 &&
2969 otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002970 // Those act as if they were invisible, so we don't need to flag them.
2971 // We do want to potentially flag touchable windows even if they have 0
2972 // opacity, since they can consume touches and alter the effects of the
2973 // user interaction (eg. apps that rely on
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08002974 // Flags::WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002975 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2976 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002977 } else if (info->ownerUid == otherInfo->ownerUid) {
2978 // If ownerUid is the same we don't generate occlusion events as there
2979 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002980 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002981 } else if (otherInfo->inputConfig.test(gui::WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002982 return false;
2983 } else if (otherInfo->displayId != info->displayId) {
2984 return false;
2985 }
2986 return true;
2987}
2988
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002989/**
2990 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2991 * untrusted, one should check:
2992 *
2993 * 1. If result.hasBlockingOcclusion is true.
2994 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2995 * BLOCK_UNTRUSTED.
2996 *
2997 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2998 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2999 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
3000 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
3001 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
3002 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
3003 *
3004 * If neither of those is true, then it means the touch can be allowed.
3005 */
3006InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05003007 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
3008 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003009 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05003010 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003011 TouchOcclusionInfo info;
3012 info.hasBlockingOcclusion = false;
3013 info.obscuringOpacity = 0;
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003014 info.obscuringUid = gui::Uid::INVALID;
3015 std::map<gui::Uid, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05003016 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003017 if (windowHandle == otherHandle) {
3018 break; // All future windows are below us. Exit early.
3019 }
chaviw98318de2021-05-19 16:45:23 -05003020 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00003021 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
3022 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003023 if (DEBUG_TOUCH_OCCLUSION) {
3024 info.debugInfo.push_back(
Harry Cutts101ee9b2023-07-06 18:04:14 +00003025 dumpWindowForTouchOcclusion(otherInfo, /*isTouchedWindow=*/false));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003026 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003027 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
3028 // we perform the checks below to see if the touch can be propagated or not based on the
3029 // window's touch occlusion mode
3030 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
3031 info.hasBlockingOcclusion = true;
3032 info.obscuringUid = otherInfo->ownerUid;
3033 info.obscuringPackage = otherInfo->packageName;
3034 break;
3035 }
3036 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003037 const auto uid = otherInfo->ownerUid;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003038 float opacity =
3039 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
3040 // Given windows A and B:
3041 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
3042 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
3043 opacityByUid[uid] = opacity;
3044 if (opacity > info.obscuringOpacity) {
3045 info.obscuringOpacity = opacity;
3046 info.obscuringUid = uid;
3047 info.obscuringPackage = otherInfo->packageName;
3048 }
3049 }
3050 }
3051 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003052 if (DEBUG_TOUCH_OCCLUSION) {
Harry Cutts101ee9b2023-07-06 18:04:14 +00003053 info.debugInfo.push_back(dumpWindowForTouchOcclusion(windowInfo, /*isTouchedWindow=*/true));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003054 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003055 return info;
3056}
3057
chaviw98318de2021-05-19 16:45:23 -05003058std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003059 bool isTouchedWindow) const {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003060 return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
Prabir Pradhan51e7db02022-02-07 06:02:57 -08003061 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
3062 "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
3063 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08003064 isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003065 info->ownerUid.toString().c_str(), info->id,
Chavi Weingarten7f019192023-08-08 20:39:01 +00003066 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frame.left,
3067 info->frame.top, info->frame.right, info->frame.bottom,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003068 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
3069 info->inputConfig.string().c_str(), toString(info->token != nullptr),
3070 info->applicationInfo.name.c_str(),
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07003071 binderToString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00003072}
3073
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003074bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
3075 if (occlusionInfo.hasBlockingOcclusion) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003076 ALOGW("Untrusted touch due to occlusion by %s/%s", occlusionInfo.obscuringPackage.c_str(),
3077 occlusionInfo.obscuringUid.toString().c_str());
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003078 return false;
3079 }
3080 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003081 ALOGW("Untrusted touch due to occlusion by %s/%s (obscuring opacity = "
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003082 "%.2f, maximum allowed = %.2f)",
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003083 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid.toString().c_str(),
Bernardo Rufinoea97d182020-08-19 14:43:14 +01003084 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
3085 return false;
3086 }
3087 return true;
3088}
3089
chaviw98318de2021-05-19 16:45:23 -05003090bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003091 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003092 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05003093 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3094 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07003095 if (windowHandle == otherHandle) {
3096 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08003097 }
chaviw98318de2021-05-19 16:45:23 -05003098 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07003099 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08003100 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003101 return true;
3102 }
3103 }
3104 return false;
3105}
3106
chaviw98318de2021-05-19 16:45:23 -05003107bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003108 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05003109 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3110 const WindowInfo* windowInfo = windowHandle->getInfo();
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 Wrightcdcd8f22016-03-22 16:52:13 -07003114 }
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->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07003118 return true;
3119 }
3120 }
3121 return false;
3122}
3123
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003124std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05003125 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003126 if (applicationHandle != nullptr) {
3127 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07003128 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003129 } else {
3130 return applicationHandle->getName();
3131 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003132 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07003133 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003134 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003135 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003136 }
3137}
3138
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003139void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00003140 if (!isUserActivityEvent(eventEntry)) {
3141 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003142 return;
3143 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003144 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05003145 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Josep del Riob3981622023-04-18 15:49:45 +00003146 const WindowInfo* windowDisablingUserActivityInfo = nullptr;
Tiger Huang721e26f2018-07-24 22:26:19 +08003147 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003148 const WindowInfo* info = focusedWindowHandle->getInfo();
Prabir Pradhan51e7db02022-02-07 06:02:57 -08003149 if (info->inputConfig.test(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY)) {
Josep del Riob3981622023-04-18 15:49:45 +00003150 windowDisablingUserActivityInfo = info;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003151 }
3152 }
3153
3154 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003155 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003156 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003157 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3158 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003159 return;
3160 }
Josep del Riob3981622023-04-18 15:49:45 +00003161 if (windowDisablingUserActivityInfo != nullptr) {
3162 if (DEBUG_DISPATCH_CYCLE) {
3163 ALOGD("Not poking user activity: disabled by window '%s'.",
3164 windowDisablingUserActivityInfo->name.c_str());
3165 }
3166 return;
3167 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003168 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003169 eventType = USER_ACTIVITY_EVENT_TOUCH;
3170 }
3171 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003172 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003173 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003174 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3175 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003176 return;
3177 }
Josep del Riob3981622023-04-18 15:49:45 +00003178 // If the key code is unknown, we don't consider it user activity
3179 if (keyEntry.keyCode == AKEYCODE_UNKNOWN) {
3180 return;
3181 }
3182 // Don't inhibit events that were intercepted or are not passed to
3183 // the apps, like system shortcuts
3184 if (windowDisablingUserActivityInfo != nullptr &&
3185 keyEntry.interceptKeyResult != KeyEntry::InterceptKeyResult::SKIP &&
3186 keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER) {
3187 if (DEBUG_DISPATCH_CYCLE) {
3188 ALOGD("Not poking user activity: disabled by window '%s'.",
3189 windowDisablingUserActivityInfo->name.c_str());
3190 }
3191 return;
3192 }
3193
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003194 eventType = USER_ACTIVITY_EVENT_BUTTON;
3195 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003196 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00003197 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003198 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08003199 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003200 break;
3201 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003202 }
3203
Prabir Pradhancef936d2021-07-21 16:17:52 +00003204 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
3205 REQUIRES(mLock) {
3206 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003207 mPolicy.pokeUserActivity(eventTime, eventType, displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00003208 };
3209 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003210}
3211
3212void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003213 const std::shared_ptr<Connection>& connection,
Prabir Pradhan24047542023-11-02 17:14:59 +00003214 std::shared_ptr<const EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003215 const InputTarget& inputTarget) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003216 ATRACE_NAME_IF(ATRACE_ENABLED(),
3217 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
3218 connection->getInputChannelName().c_str(), eventEntry->id));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003219 if (DEBUG_DISPATCH_CYCLE) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003220 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=%s, "
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08003221 "globalScaleFactor=%f, pointerIds=%s %s",
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003222 connection->getInputChannelName().c_str(), inputTarget.flags.string().c_str(),
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08003223 inputTarget.globalScaleFactor, bitsetToString(inputTarget.pointerIds).c_str(),
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003224 inputTarget.getPointerInfoString().c_str());
3225 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003226
3227 // Skip this event if the connection status is not normal.
3228 // We don't want to enqueue additional outbound events if the connection is broken.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003229 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003230 if (DEBUG_DISPATCH_CYCLE) {
3231 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003232 connection->getInputChannelName().c_str(),
3233 ftl::enum_string(connection->status).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003234 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003235 return;
3236 }
3237
3238 // Split a motion event if needed.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003239 if (inputTarget.flags.test(InputTarget::Flags::SPLIT)) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003240 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003241 "Entry type %s should not have Flags::SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08003242 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003243
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003244 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003245 if (inputTarget.pointerIds.count() != originalMotionEntry.getPointerCount()) {
Siarhei Vishniakou16e4fa02023-02-16 17:48:56 -08003246 if (!inputTarget.firstDownTimeInTarget.has_value()) {
3247 logDispatchStateLocked();
3248 LOG(FATAL) << "Splitting motion events requires a down time to be set for the "
3249 "target on connection "
3250 << connection->getInputChannelName() << " for "
3251 << originalMotionEntry.getDescription();
3252 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003253 std::unique_ptr<MotionEntry> splitMotionEntry =
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00003254 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds,
3255 inputTarget.firstDownTimeInTarget.value());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003256 if (!splitMotionEntry) {
3257 return; // split event was dropped
3258 }
Arthur Hungb3307ee2021-10-14 10:57:37 +00003259 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
3260 std::string reason = std::string("reason=pointer cancel on split window");
3261 android_log_event_list(LOGTAG_INPUT_CANCEL)
3262 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3263 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003264 if (DEBUG_FOCUS) {
3265 ALOGD("channel '%s' ~ Split motion event.",
3266 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003267 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01003268 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003269 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
3270 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003271 return;
3272 }
3273 }
3274
3275 // Not splitting. Enqueue dispatch entries for the event as is.
3276 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
3277}
3278
3279void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003280 const std::shared_ptr<Connection>& connection,
Prabir Pradhan24047542023-11-02 17:14:59 +00003281 std::shared_ptr<const EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003282 const InputTarget& inputTarget) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003283 ATRACE_NAME_IF(ATRACE_ENABLED(),
3284 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
3285 connection->getInputChannelName().c_str(), eventEntry->id));
Siarhei Vishniakou5cee1e32022-11-29 12:35:39 -08003286 LOG_ALWAYS_FATAL_IF(!inputTarget.flags.any(InputTarget::DISPATCH_MASK),
3287 "No dispatch flags are set for %s", eventEntry->getDescription().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003288
hongzuo liu95785e22022-09-06 02:51:35 +00003289 const bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003290
3291 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07003292 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003293 InputTarget::Flags::DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07003294 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003295 InputTarget::Flags::DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07003296 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003297 InputTarget::Flags::DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07003298 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003299 InputTarget::Flags::DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07003300 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003301 InputTarget::Flags::DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07003302 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003303 InputTarget::Flags::DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003304
3305 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003306 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003307 startDispatchCycleLocked(currentTime, connection);
3308 }
3309}
3310
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003311void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,
Prabir Pradhan24047542023-11-02 17:14:59 +00003312 std::shared_ptr<const EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003313 const InputTarget& inputTarget,
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003314 ftl::Flags<InputTarget::Flags> dispatchMode) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003315 ftl::Flags<InputTarget::Flags> inputTargetFlags = inputTarget.flags;
3316 if (!inputTargetFlags.any(dispatchMode)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003317 return;
3318 }
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003319
3320 inputTargetFlags.clear(InputTarget::DISPATCH_MASK);
3321 inputTargetFlags |= dispatchMode;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003322
3323 // This is a new event.
3324 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003325 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003326 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003328 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
3329 // different EventEntry than what was passed in.
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003330 eventEntry = dispatchEntry->eventEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003331 // Apply target flags and update the connection's input state.
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003332 switch (eventEntry->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003333 case EventEntry::Type::KEY: {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003334 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*eventEntry);
3335 if (!connection->inputState.trackKey(keyEntry, keyEntry.flags)) {
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -07003336 LOG(WARNING) << "channel " << connection->getInputChannelName()
3337 << "~ dropping inconsistent event: " << *dispatchEntry;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003338 return; // skip the inconsistent event
3339 }
3340 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003341 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003342
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003343 case EventEntry::Type::MOTION: {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003344 std::shared_ptr<const MotionEntry> resolvedMotion =
3345 std::static_pointer_cast<const MotionEntry>(eventEntry);
3346 {
3347 // Determine the resolved motion entry.
3348 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
3349 int32_t resolvedAction = motionEntry.action;
3350 int32_t resolvedFlags = motionEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003351
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003352 if (dispatchMode.test(InputTarget::Flags::DISPATCH_AS_OUTSIDE)) {
3353 resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
3354 } else if (dispatchMode.test(InputTarget::Flags::DISPATCH_AS_HOVER_EXIT)) {
3355 resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
3356 } else if (dispatchMode.test(InputTarget::Flags::DISPATCH_AS_HOVER_ENTER)) {
3357 resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3358 } else if (dispatchMode.test(InputTarget::Flags::DISPATCH_AS_SLIPPERY_EXIT)) {
3359 resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
3360 } else if (dispatchMode.test(InputTarget::Flags::DISPATCH_AS_SLIPPERY_ENTER)) {
3361 resolvedAction = AMOTION_EVENT_ACTION_DOWN;
3362 }
3363 if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
3364 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3365 motionEntry.displayId)) {
3366 if (DEBUG_DISPATCH_CYCLE) {
3367 LOG(DEBUG) << "channel '" << connection->getInputChannelName().c_str()
3368 << "' ~ enqueueDispatchEntryLocked: filling in missing hover "
3369 "enter event";
3370 }
3371 resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3372 }
3373
3374 if (resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
3375 resolvedFlags |= AMOTION_EVENT_FLAG_CANCELED;
3376 }
3377 if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) {
3378 resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3379 }
3380 if (dispatchEntry->targetFlags.test(
3381 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED)) {
3382 resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3383 }
3384
3385 dispatchEntry->resolvedFlags = resolvedFlags;
3386 if (resolvedAction != motionEntry.action) {
3387 // Generate a new MotionEntry with a new eventId using the resolved action and
3388 // flags.
3389 resolvedMotion =
3390 std::make_shared<MotionEntry>(mIdGenerator.nextId(),
3391 motionEntry.injectionState,
3392 motionEntry.eventTime,
3393 motionEntry.deviceId, motionEntry.source,
3394 motionEntry.displayId,
3395 motionEntry.policyFlags, resolvedAction,
3396 motionEntry.actionButton, resolvedFlags,
3397 motionEntry.metaState,
3398 motionEntry.buttonState,
3399 motionEntry.classification,
3400 motionEntry.edgeFlags,
3401 motionEntry.xPrecision,
3402 motionEntry.yPrecision,
3403 motionEntry.xCursorPosition,
3404 motionEntry.yCursorPosition,
3405 motionEntry.downTime,
3406 motionEntry.pointerProperties,
3407 motionEntry.pointerCoords);
3408 if (ATRACE_ENABLED()) {
3409 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3410 ") to MotionEvent(id=0x%" PRIx32 ").",
3411 motionEntry.id, resolvedMotion->id);
3412 ATRACE_NAME(message.c_str());
3413 }
3414
3415 // Set the resolved motion entry in the DispatchEntry.
3416 dispatchEntry->eventEntry = resolvedMotion;
3417 eventEntry = resolvedMotion;
3418 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003419 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003420
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003421 // Check if we need to cancel any of the ongoing gestures. We don't support multiple
3422 // devices being active at the same time in the same window, so if a new device is
3423 // active, cancel the gesture from the old device.
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003424 std::unique_ptr<EventEntry> cancelEvent =
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003425 connection->inputState.cancelConflictingInputStream(*resolvedMotion);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003426 if (cancelEvent != nullptr) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003427 LOG(INFO) << "Canceling pointers for device " << resolvedMotion->deviceId << " in "
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07003428 << connection->getInputChannelName() << " with event "
3429 << cancelEvent->getDescription();
3430 std::unique_ptr<DispatchEntry> cancelDispatchEntry =
3431 createDispatchEntry(inputTarget, std::move(cancelEvent),
3432 InputTarget::Flags::DISPATCH_AS_IS);
3433
3434 // Send these cancel events to the queue before sending the event from the new
3435 // device.
3436 connection->outboundQueue.emplace_back(std::move(cancelDispatchEntry));
3437 }
3438
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003439 if (!connection->inputState.trackMotion(*resolvedMotion,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003440 dispatchEntry->resolvedFlags)) {
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -07003441 LOG(WARNING) << "channel " << connection->getInputChannelName()
3442 << "~ dropping inconsistent event: " << *dispatchEntry;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003443 return; // skip the inconsistent event
3444 }
3445
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003446 if ((resolvedMotion->flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3447 (resolvedMotion->policyFlags & POLICY_FLAG_TRUSTED)) {
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003448 // Skip reporting pointer down outside focus to the policy.
3449 break;
3450 }
3451
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003452 dispatchPointerDownOutsideFocus(resolvedMotion->source, resolvedMotion->action,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003453 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003454
3455 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003456 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003457 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003458 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003459 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3460 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003461 break;
3462 }
Chris Yef59a2f42020-10-16 12:55:26 -07003463 case EventEntry::Type::SENSOR: {
3464 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3465 break;
3466 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003467 case EventEntry::Type::CONFIGURATION_CHANGED:
3468 case EventEntry::Type::DEVICE_RESET: {
3469 LOG_ALWAYS_FATAL("%s events should not go to apps",
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003470 ftl::enum_string(eventEntry->type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003471 break;
3472 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003473 }
3474
3475 // Remember that we are waiting for this dispatch to complete.
3476 if (dispatchEntry->hasForegroundTarget()) {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003477 incrementPendingForegroundDispatches(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003478 }
3479
3480 // Enqueue the dispatch entry.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003481 connection->outboundQueue.emplace_back(std::move(dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003482 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003483}
3484
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003485/**
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003486 * This function is for debugging and metrics collection. It has two roles.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003487 *
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003488 * The first role is to log input interaction with windows, which helps determine what the user was
3489 * interacting with. For example, if user is touching launcher, we will see an input_interaction log
3490 * that user started interacting with launcher window, as well as any other window that received
3491 * that gesture, such as the wallpaper or other spy windows. A new input_interaction is only logged
3492 * when the set of tokens that received the event changes. It is not logged again as long as the
3493 * user is interacting with the same windows.
3494 *
3495 * The second role is to track input device activity for metrics collection. For each input event,
3496 * we report the set of UIDs that the input device interacted with to the policy. Unlike for the
3497 * input_interaction logs, the device interaction is reported even when the set of interaction
3498 * tokens do not change.
3499 *
3500 * For these purposes, we do not count ACTION_OUTSIDE, ACTION_UP and ACTION_CANCEL actions as
3501 * interaction. This includes up and cancel events for both keys and motions.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003502 */
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003503void InputDispatcher::processInteractionsLocked(const EventEntry& entry,
3504 const std::vector<InputTarget>& targets) {
3505 int32_t deviceId;
3506 nsecs_t eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003507 // Skip ACTION_UP events, and all events other than keys and motions
3508 if (entry.type == EventEntry::Type::KEY) {
3509 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3510 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3511 return;
3512 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003513 deviceId = keyEntry.deviceId;
3514 eventTime = keyEntry.eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003515 } else if (entry.type == EventEntry::Type::MOTION) {
3516 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3517 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003518 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
3519 MotionEvent::getActionMasked(motionEntry.action) == AMOTION_EVENT_ACTION_POINTER_UP) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003520 return;
3521 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003522 deviceId = motionEntry.deviceId;
3523 eventTime = motionEntry.eventTime;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003524 } else {
3525 return; // Not a key or a motion
3526 }
3527
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00003528 std::set<gui::Uid> interactionUids;
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003529 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003530 std::vector<std::shared_ptr<Connection>> newConnections;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003531 for (const InputTarget& target : targets) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003532 if (target.flags.test(InputTarget::Flags::DISPATCH_AS_OUTSIDE)) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003533 continue; // Skip windows that receive ACTION_OUTSIDE
3534 }
3535
3536 sp<IBinder> token = target.inputChannel->getConnectionToken();
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003537 std::shared_ptr<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003538 if (connection == nullptr) {
3539 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003540 }
3541 newConnectionTokens.insert(std::move(token));
3542 newConnections.emplace_back(connection);
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003543 if (target.windowHandle) {
3544 interactionUids.emplace(target.windowHandle->getInfo()->ownerUid);
3545 }
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003546 }
Prabir Pradhan8ede1d12023-05-08 19:37:44 +00003547
3548 auto command = [this, deviceId, eventTime, uids = std::move(interactionUids)]()
3549 REQUIRES(mLock) {
3550 scoped_unlock unlock(mLock);
3551 mPolicy.notifyDeviceInteraction(deviceId, eventTime, uids);
3552 };
3553 postCommandLocked(std::move(command));
3554
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003555 if (newConnectionTokens == mInteractionConnectionTokens) {
3556 return; // no change
3557 }
3558 mInteractionConnectionTokens = newConnectionTokens;
3559
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003560 std::string targetList;
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003561 for (const std::shared_ptr<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003562 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003563 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003564 std::string message = "Interaction with: " + targetList;
3565 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003566 message += "<none>";
3567 }
3568 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3569}
3570
chaviwfd6d3512019-03-25 13:23:49 -07003571void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003572 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003573 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003574 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3575 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003576 return;
3577 }
3578
Vishnu Nairc519ff72021-01-21 08:23:08 -08003579 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003580 if (focusedToken == token) {
3581 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003582 return;
3583 }
3584
Prabir Pradhancef936d2021-07-21 16:17:52 +00003585 auto command = [this, token]() REQUIRES(mLock) {
3586 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003587 mPolicy.onPointerDownOutsideFocus(token);
Prabir Pradhancef936d2021-07-21 16:17:52 +00003588 };
3589 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003590}
3591
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003592status_t InputDispatcher::publishMotionEvent(Connection& connection,
3593 DispatchEntry& dispatchEntry) const {
3594 const EventEntry& eventEntry = *(dispatchEntry.eventEntry);
3595 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3596
3597 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003598 const PointerCoords* usingCoords = motionEntry.pointerCoords.data();
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003599
3600 // Set the X and Y offset and X and Y scale depending on the input source.
3601 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003602 !(dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS))) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003603 float globalScaleFactor = dispatchEntry.globalScaleFactor;
3604 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003605 for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003606 scaledCoords[i] = motionEntry.pointerCoords[i];
3607 // Don't apply window scale here since we don't want scale to affect raw
3608 // coordinates. The scale will be sent back to the client and applied
3609 // later when requesting relative coordinates.
Harry Cutts33476232023-01-30 19:57:29 +00003610 scaledCoords[i].scale(globalScaleFactor, /*windowXScale=*/1, /*windowYScale=*/1);
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003611 }
3612 usingCoords = scaledCoords;
3613 }
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08003614 } else if (dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS)) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003615 // We don't want the dispatch target to know the coordinates
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07003616 for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003617 scaledCoords[i].clear();
3618 }
3619 usingCoords = scaledCoords;
3620 }
3621
3622 std::array<uint8_t, 32> hmac = getSignature(motionEntry, dispatchEntry);
3623
3624 // Publish the motion event.
3625 return connection.inputPublisher
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003626 .publishMotionEvent(dispatchEntry.seq, motionEntry.id, motionEntry.deviceId,
3627 motionEntry.source, motionEntry.displayId, std::move(hmac),
3628 motionEntry.action, motionEntry.actionButton,
3629 dispatchEntry.resolvedFlags, motionEntry.edgeFlags,
3630 motionEntry.metaState, motionEntry.buttonState,
3631 motionEntry.classification, dispatchEntry.transform,
3632 motionEntry.xPrecision, motionEntry.yPrecision,
3633 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
3634 dispatchEntry.rawTransform, motionEntry.downTime,
3635 motionEntry.eventTime, motionEntry.getPointerCount(),
3636 motionEntry.pointerProperties.data(), usingCoords);
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003637}
3638
Michael Wrightd02c5b62014-02-10 15:10:22 -08003639void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003640 const std::shared_ptr<Connection>& connection) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00003641 ATRACE_NAME_IF(ATRACE_ENABLED(),
3642 StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
3643 connection->getInputChannelName().c_str()));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003644 if (DEBUG_DISPATCH_CYCLE) {
3645 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3646 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003647
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003648 while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003649 std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003650 dispatchEntry->deliveryTime = currentTime;
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08003651 const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003652 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003653
3654 // Publish the event.
3655 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003656 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3657 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003658 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003659 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3660 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003661 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003662 LOG(INFO) << "Publishing " << *dispatchEntry << " to "
3663 << connection->getInputChannelName();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003664 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003665
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003666 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003667 status = connection->inputPublisher
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003668 .publishKeyEvent(dispatchEntry->seq, keyEntry.id,
3669 keyEntry.deviceId, keyEntry.source,
3670 keyEntry.displayId, std::move(hmac),
3671 keyEntry.action, dispatchEntry->resolvedFlags,
3672 keyEntry.keyCode, keyEntry.scanCode,
3673 keyEntry.metaState, keyEntry.repeatCount,
3674 keyEntry.downTime, keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003675 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003676 }
3677
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003678 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003679 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003680 LOG(INFO) << "Publishing " << *dispatchEntry << " to "
3681 << connection->getInputChannelName();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08003682 }
Siarhei Vishniakoucce7e112022-10-25 13:31:17 -07003683 status = publishMotionEvent(*connection, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003684 break;
3685 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003686
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003687 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003688 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003689 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003690 focusEntry.id,
Antonio Kantek3cfec7b2021-11-05 18:26:17 -07003691 focusEntry.hasFocus);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003692 break;
3693 }
3694
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003695 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3696 const TouchModeEntry& touchModeEntry =
3697 static_cast<const TouchModeEntry&>(eventEntry);
3698 status = connection->inputPublisher
3699 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3700 touchModeEntry.inTouchMode);
3701
3702 break;
3703 }
3704
Prabir Pradhan99987712020-11-10 18:43:05 -08003705 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3706 const auto& captureEntry =
3707 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3708 status = connection->inputPublisher
3709 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003710 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003711 break;
3712 }
3713
arthurhungb89ccb02020-12-30 16:19:01 +08003714 case EventEntry::Type::DRAG: {
3715 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3716 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3717 dragEntry.id, dragEntry.x,
3718 dragEntry.y,
3719 dragEntry.isExiting);
3720 break;
3721 }
3722
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003723 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003724 case EventEntry::Type::DEVICE_RESET:
3725 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003726 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003727 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003728 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003729 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003730 }
3731
3732 // Check the result.
3733 if (status) {
3734 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003735 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003736 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003737 "This is unexpected because the wait queue is empty, so the pipe "
3738 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003739 "event to it, status=%s(%d)",
3740 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3741 status);
Harry Cutts33476232023-01-30 19:57:29 +00003742 abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003743 } else {
3744 // Pipe is full and we are waiting for the app to finish process some events
3745 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003746 if (DEBUG_DISPATCH_CYCLE) {
3747 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3748 "waiting for the application to catch up",
3749 connection->getInputChannelName().c_str());
3750 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003751 }
3752 } else {
3753 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003754 "status=%s(%d)",
3755 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3756 status);
Harry Cutts33476232023-01-30 19:57:29 +00003757 abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003758 }
3759 return;
3760 }
3761
3762 // Re-enqueue the event on the wait queue.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003763 const nsecs_t timeoutTime = dispatchEntry->timeoutTime;
3764 connection->waitQueue.emplace_back(std::move(dispatchEntry));
3765 connection->outboundQueue.erase(connection->outboundQueue.begin());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003766 traceOutboundQueueLength(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003767 if (connection->responsive) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003768 mAnrTracker.insert(timeoutTime, connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003769 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003770 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003771 }
3772}
3773
chaviw09c8d2d2020-08-24 15:48:26 -07003774std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3775 size_t size;
3776 switch (event.type) {
3777 case VerifiedInputEvent::Type::KEY: {
3778 size = sizeof(VerifiedKeyEvent);
3779 break;
3780 }
3781 case VerifiedInputEvent::Type::MOTION: {
3782 size = sizeof(VerifiedMotionEvent);
3783 break;
3784 }
3785 }
3786 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3787 return mHmacKeyManager.sign(start, size);
3788}
3789
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003790const std::array<uint8_t, 32> InputDispatcher::getSignature(
3791 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhan2a2da1d2023-11-03 02:16:20 +00003792 const int32_t actionMasked = MotionEvent::getActionMasked(motionEntry.action);
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003793 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003794 // Only sign events up and down events as the purely move events
3795 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003796 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003797 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003798
3799 VerifiedMotionEvent verifiedEvent =
3800 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3801 verifiedEvent.actionMasked = actionMasked;
3802 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3803 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003804}
3805
3806const std::array<uint8_t, 32> InputDispatcher::getSignature(
3807 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3808 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3809 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003810 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003811}
3812
Michael Wrightd02c5b62014-02-10 15:10:22 -08003813void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003814 const std::shared_ptr<Connection>& connection,
3815 uint32_t seq, bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003816 if (DEBUG_DISPATCH_CYCLE) {
3817 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3818 connection->getInputChannelName().c_str(), seq, toString(handled));
3819 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003820
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003821 if (connection->status == Connection::Status::BROKEN ||
3822 connection->status == Connection::Status::ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003823 return;
3824 }
3825
3826 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003827 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3828 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3829 };
3830 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003831}
3832
3833void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003834 const std::shared_ptr<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003835 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003836 if (DEBUG_DISPATCH_CYCLE) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07003837 LOG(INFO) << "channel '" << connection->getInputChannelName() << "'~ " << __func__
3838 << " - notify=" << toString(notify);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003839 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003840
3841 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003842 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003843 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003844 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003845 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003846
3847 // The connection appears to be unrecoverably broken.
3848 // Ignore already broken or zombie connections.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003849 if (connection->status == Connection::Status::NORMAL) {
3850 connection->status = Connection::Status::BROKEN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003851
3852 if (notify) {
3853 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003854 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3855 connection->getInputChannelName().c_str());
3856
3857 auto command = [this, connection]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003858 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00003859 mPolicy.notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Prabir Pradhancef936d2021-07-21 16:17:52 +00003860 };
3861 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003862 }
3863 }
3864}
3865
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003866void InputDispatcher::drainDispatchQueue(std::deque<std::unique_ptr<DispatchEntry>>& queue) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003867 while (!queue.empty()) {
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003868 releaseDispatchEntry(std::move(queue.front()));
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003869 queue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003870 }
3871}
3872
Prabir Pradhan8c90d782023-09-15 21:16:44 +00003873void InputDispatcher::releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003874 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003875 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003876 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003877}
3878
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003879int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3880 std::scoped_lock _l(mLock);
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003881 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003882 if (connection == nullptr) {
3883 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3884 connectionToken.get(), events);
3885 return 0; // remove the callback
3886 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003887
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003888 bool notify;
3889 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3890 if (!(events & ALOOPER_EVENT_INPUT)) {
3891 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3892 "events=0x%x",
3893 connection->getInputChannelName().c_str(), events);
3894 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003895 }
3896
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003897 nsecs_t currentTime = now();
3898 bool gotOne = false;
3899 status_t status = OK;
3900 for (;;) {
3901 Result<InputPublisher::ConsumerResponse> result =
3902 connection->inputPublisher.receiveConsumerResponse();
3903 if (!result.ok()) {
3904 status = result.error().code();
3905 break;
3906 }
3907
3908 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3909 const InputPublisher::Finished& finish =
3910 std::get<InputPublisher::Finished>(*result);
3911 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3912 finish.consumeTime);
3913 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003914 if (shouldReportMetricsForConnection(*connection)) {
3915 const InputPublisher::Timeline& timeline =
3916 std::get<InputPublisher::Timeline>(*result);
3917 mLatencyTracker
3918 .trackGraphicsLatency(timeline.inputEventId,
3919 connection->inputChannel->getConnectionToken(),
3920 std::move(timeline.graphicsTimeline));
3921 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003922 }
3923 gotOne = true;
3924 }
3925 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003926 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003927 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003928 return 1;
3929 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003930 }
3931
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003932 notify = status != DEAD_OBJECT || !connection->monitor;
3933 if (notify) {
3934 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3935 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3936 status);
3937 }
3938 } else {
3939 // Monitor channels are never explicitly unregistered.
3940 // We do it automatically when the remote endpoint is closed so don't warn about them.
3941 const bool stillHaveWindowHandle =
3942 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3943 notify = !connection->monitor && stillHaveWindowHandle;
3944 if (notify) {
3945 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3946 connection->getInputChannelName().c_str(), events);
3947 }
3948 }
3949
3950 // Remove the channel.
3951 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3952 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003953}
3954
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003955void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003956 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003957 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003958 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003959 }
3960}
3961
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003962void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003963 const CancelationOptions& options) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08003964 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003965 for (const Monitor& monitor : monitors) {
3966 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003967 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003968 }
3969}
3970
Michael Wrightd02c5b62014-02-10 15:10:22 -08003971void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003972 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003973 std::shared_ptr<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003974 if (connection == nullptr) {
3975 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003977
3978 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003979}
3980
3981void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07003982 const std::shared_ptr<Connection>& connection, const CancelationOptions& options) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003983 if (connection->status == Connection::Status::BROKEN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003984 return;
3985 }
3986
3987 nsecs_t currentTime = now();
3988
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003989 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003990 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003991
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003992 if (cancelationEvents.empty()) {
3993 return;
3994 }
Vaibhav Devmurari110ba322023-11-17 10:47:16 +00003995
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003996 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3997 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Siarhei Vishniakou2e3e4432023-02-09 18:34:11 -08003998 "with reality: %s, mode=%s.",
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003999 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
Siarhei Vishniakou2e3e4432023-02-09 18:34:11 -08004000 ftl::enum_string(options.mode).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004001 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08004002
Arthur Hungb3307ee2021-10-14 10:57:37 +00004003 std::string reason = std::string("reason=").append(options.reason);
4004 android_log_event_list(LOGTAG_INPUT_CANCEL)
4005 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
4006
hongzuo liu95785e22022-09-06 02:51:35 +00004007 const bool wasEmpty = connection->outboundQueue.empty();
Prabir Pradhan16463382023-10-12 23:03:19 +00004008 // The target to use if we don't find a window associated with the channel.
4009 const InputTarget fallbackTarget{.inputChannel = connection->inputChannel,
4010 .flags = InputTarget::Flags::DISPATCH_AS_IS};
4011 const auto& token = connection->inputChannel->getConnectionToken();
hongzuo liu95785e22022-09-06 02:51:35 +00004012
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004013 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004014 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004015 std::vector<InputTarget> targets{};
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004016
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004017 switch (cancelationEventEntry->type) {
4018 case EventEntry::Type::KEY: {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004019 const auto& keyEntry = static_cast<const KeyEntry&>(*cancelationEventEntry);
Prabir Pradhan16463382023-10-12 23:03:19 +00004020 const std::optional<int32_t> targetDisplay = keyEntry.displayId != ADISPLAY_ID_NONE
4021 ? std::make_optional(keyEntry.displayId)
4022 : std::nullopt;
4023 if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
4024 addWindowTargetLocked(window, InputTarget::Flags::DISPATCH_AS_IS,
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07004025 keyEntry.downTime, targets);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004026 } else {
4027 targets.emplace_back(fallbackTarget);
4028 }
4029 logOutboundKeyDetails("cancel - ", keyEntry);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004030 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004031 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004032 case EventEntry::Type::MOTION: {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004033 const auto& motionEntry = static_cast<const MotionEntry&>(*cancelationEventEntry);
Prabir Pradhan16463382023-10-12 23:03:19 +00004034 const std::optional<int32_t> targetDisplay =
4035 motionEntry.displayId != ADISPLAY_ID_NONE
4036 ? std::make_optional(motionEntry.displayId)
4037 : std::nullopt;
4038 if (const auto& window = getWindowHandleLocked(token, targetDisplay); window) {
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004039 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004040 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004041 pointerIndex++) {
4042 pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4043 }
Vaibhav Devmurari110ba322023-11-17 10:47:16 +00004044 if (mDragState && mDragState->dragWindow->getToken() == token &&
4045 pointerIds.test(mDragState->pointerId)) {
4046 LOG(INFO) << __func__
4047 << ": Canceling drag and drop because the pointers for the drag "
4048 "window are being canceled.";
4049 sendDropWindowCommandLocked(nullptr, /*x=*/0, /*y=*/0);
4050 mDragState.reset();
4051 }
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07004052 addPointerWindowTargetLocked(window, InputTarget::Flags::DISPATCH_AS_IS,
4053 pointerIds, motionEntry.downTime, targets);
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004054 } else {
4055 targets.emplace_back(fallbackTarget);
4056 const auto it = mDisplayInfos.find(motionEntry.displayId);
4057 if (it != mDisplayInfos.end()) {
4058 targets.back().displayTransform = it->second.transform;
4059 targets.back().setDefaultPointerTransform(it->second.transform);
4060 }
4061 }
4062 logOutboundMotionDetails("cancel - ", motionEntry);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004063 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004064 }
Prabir Pradhan99987712020-11-10 18:43:05 -08004065 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004066 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08004067 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
4068 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08004069 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08004070 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004071 break;
4072 }
4073 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07004074 case EventEntry::Type::DEVICE_RESET:
4075 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004076 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08004077 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004078 break;
4079 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004080 }
4081
Prabir Pradhan112b1ad2023-09-21 09:53:53 +00004082 if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
4083 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), targets[0],
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08004084 InputTarget::Flags::DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004085 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08004086
hongzuo liu95785e22022-09-06 02:51:35 +00004087 // If the outbound queue was previously empty, start the dispatch cycle going.
4088 if (wasEmpty && !connection->outboundQueue.empty()) {
4089 startDispatchCycleLocked(currentTime, connection);
4090 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004091}
4092
Svet Ganov5d3bc372020-01-26 23:11:07 -08004093void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07004094 const nsecs_t downTime, const std::shared_ptr<Connection>& connection,
Arthur Hungc539dbb2022-12-08 07:45:36 +00004095 ftl::Flags<InputTarget::Flags> targetFlags) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08004096 if (connection->status == Connection::Status::BROKEN) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004097 return;
4098 }
4099
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004100 std::vector<std::unique_ptr<EventEntry>> downEvents =
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004101 connection->inputState.synthesizePointerDownEvents(downTime);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004102
4103 if (downEvents.empty()) {
4104 return;
4105 }
4106
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004107 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004108 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
4109 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004110 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08004111
chaviw98318de2021-05-19 16:45:23 -05004112 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08004113 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Svet Ganov5d3bc372020-01-26 23:11:07 -08004114
hongzuo liu95785e22022-09-06 02:51:35 +00004115 const bool wasEmpty = connection->outboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004116 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004117 std::vector<InputTarget> targets{};
Svet Ganov5d3bc372020-01-26 23:11:07 -08004118 switch (downEventEntry->type) {
4119 case EventEntry::Type::MOTION: {
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004120 const auto& motionEntry = static_cast<const MotionEntry&>(*downEventEntry);
4121 if (windowHandle != nullptr) {
4122 std::bitset<MAX_POINTER_ID + 1> pointerIds;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004123 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004124 pointerIndex++) {
4125 pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4126 }
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07004127 addPointerWindowTargetLocked(windowHandle, targetFlags, pointerIds,
4128 motionEntry.downTime, targets);
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004129 } else {
4130 targets.emplace_back(InputTarget{.inputChannel = connection->inputChannel,
4131 .flags = targetFlags});
4132 const auto it = mDisplayInfos.find(motionEntry.displayId);
4133 if (it != mDisplayInfos.end()) {
4134 targets.back().displayTransform = it->second.transform;
4135 targets.back().setDefaultPointerTransform(it->second.transform);
4136 }
4137 }
4138 logOutboundMotionDetails("down - ", motionEntry);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004139 break;
4140 }
4141
4142 case EventEntry::Type::KEY:
4143 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07004144 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08004145 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08004146 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07004147 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08004148 case EventEntry::Type::SENSOR:
4149 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004150 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08004151 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08004152 break;
4153 }
4154 }
4155
Prabir Pradhan1c29a092023-09-21 10:29:29 +00004156 if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
4157 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), targets[0],
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08004158 InputTarget::Flags::DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004159 }
4160
hongzuo liu95785e22022-09-06 02:51:35 +00004161 // If the outbound queue was previously empty, start the dispatch cycle going.
4162 if (wasEmpty && !connection->outboundQueue.empty()) {
4163 startDispatchCycleLocked(downTime, connection);
4164 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08004165}
4166
Arthur Hungc539dbb2022-12-08 07:45:36 +00004167void InputDispatcher::synthesizeCancelationEventsForWindowLocked(
4168 const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options) {
4169 if (windowHandle != nullptr) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07004170 std::shared_ptr<Connection> wallpaperConnection =
4171 getConnectionLocked(windowHandle->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00004172 if (wallpaperConnection != nullptr) {
4173 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection, options);
4174 }
4175 }
4176}
4177
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004178std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004179 const MotionEntry& originalMotionEntry, std::bitset<MAX_POINTER_ID + 1> pointerIds,
4180 nsecs_t splitDownTime) {
4181 ALOG_ASSERT(pointerIds.any());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004182
4183 uint32_t splitPointerIndexMap[MAX_POINTERS];
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004184 std::vector<PointerProperties> splitPointerProperties;
4185 std::vector<PointerCoords> splitPointerCoords;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004186
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004187 uint32_t originalPointerCount = originalMotionEntry.getPointerCount();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004188 uint32_t splitPointerCount = 0;
4189
4190 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004191 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004192 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004193 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004194 uint32_t pointerId = uint32_t(pointerProperties.id);
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004195 if (pointerIds.test(pointerId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004196 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004197 splitPointerProperties.push_back(pointerProperties);
4198 splitPointerCoords.push_back(originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004199 splitPointerCount += 1;
4200 }
4201 }
4202
4203 if (splitPointerCount != pointerIds.count()) {
4204 // This is bad. We are missing some of the pointers that we expected to deliver.
4205 // Most likely this indicates that we received an ACTION_MOVE events that has
4206 // different pointer ids than we expected based on the previous ACTION_DOWN
4207 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
4208 // in this way.
4209 ALOGW("Dropping split motion event because the pointer count is %d but "
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004210 "we expected there to be %zu pointers. This probably means we received "
Siarhei Vishniakou16e4fa02023-02-16 17:48:56 -08004211 "a broken sequence of pointer ids from the input device: %s",
4212 splitPointerCount, pointerIds.count(), originalMotionEntry.getDescription().c_str());
Yi Kong9b14ac62018-07-17 13:48:38 -07004213 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004214 }
4215
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004216 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004217 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004218 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
4219 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Siarhei Vishniakou5b9766d2023-07-18 14:06:29 -07004220 int32_t originalPointerIndex = MotionEvent::getActionIndex(action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004221 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07004222 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004223 uint32_t pointerId = uint32_t(pointerProperties.id);
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08004224 if (pointerIds.test(pointerId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004225 if (pointerIds.count() == 1) {
4226 // The first/last pointer went down/up.
4227 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004228 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08004229 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
4230 ? AMOTION_EVENT_ACTION_CANCEL
4231 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004232 } else {
4233 // A secondary pointer went down/up.
4234 uint32_t splitPointerIndex = 0;
4235 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
4236 splitPointerIndex += 1;
4237 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004238 action = maskedAction |
4239 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004240 }
4241 } else {
4242 // An unrelated pointer changed.
4243 action = AMOTION_EVENT_ACTION_MOVE;
4244 }
4245 }
4246
Siarhei Vishniakou59e302b2023-06-05 08:04:53 -07004247 if (action == AMOTION_EVENT_ACTION_DOWN && splitDownTime != originalMotionEntry.eventTime) {
4248 logDispatchStateLocked();
4249 LOG_ALWAYS_FATAL("Split motion event has mismatching downTime and eventTime for "
4250 "ACTION_DOWN, motionEntry=%s, splitDownTime=%" PRId64,
4251 originalMotionEntry.getDescription().c_str(), splitDownTime);
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004252 }
4253
Garfield Tanff1f1bb2020-01-28 13:24:04 -08004254 int32_t newId = mIdGenerator.nextId();
Prabir Pradhan2dac8b82023-09-06 01:11:51 +00004255 ATRACE_NAME_IF(ATRACE_ENABLED(),
4256 StringPrintf("Split MotionEvent(id=0x%" PRIx32 ") to MotionEvent(id=0x%" PRIx32
4257 ").",
4258 originalMotionEntry.id, newId));
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004259 std::unique_ptr<MotionEntry> splitMotionEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004260 std::make_unique<MotionEntry>(newId, originalMotionEntry.injectionState,
4261 originalMotionEntry.eventTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004262 originalMotionEntry.deviceId, originalMotionEntry.source,
4263 originalMotionEntry.displayId,
4264 originalMotionEntry.policyFlags, action,
4265 originalMotionEntry.actionButton,
4266 originalMotionEntry.flags, originalMotionEntry.metaState,
4267 originalMotionEntry.buttonState,
4268 originalMotionEntry.classification,
4269 originalMotionEntry.edgeFlags,
4270 originalMotionEntry.xPrecision,
4271 originalMotionEntry.yPrecision,
4272 originalMotionEntry.xCursorPosition,
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00004273 originalMotionEntry.yCursorPosition, splitDownTime,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004274 splitPointerProperties, splitPointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004275
Michael Wrightd02c5b62014-02-10 15:10:22 -08004276 return splitMotionEntry;
4277}
4278
Asmita Poddardd9a6cd2023-09-26 15:35:12 +00004279void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
4280 std::scoped_lock _l(mLock);
4281 mLatencyTracker.setInputDevices(args.inputDeviceInfos);
4282}
4283
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004284void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004285 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004286 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args.eventTime);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004287 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004288
Antonio Kantekf16f2832021-09-28 04:39:20 +00004289 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004290 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004291 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004292
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004293 std::unique_ptr<ConfigurationChangedEntry> newEntry =
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004294 std::make_unique<ConfigurationChangedEntry>(args.id, args.eventTime);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004295 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004296 } // release lock
4297
4298 if (needWake) {
4299 mLooper->wake();
4300 }
4301}
4302
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004303void InputDispatcher::notifyKey(const NotifyKeyArgs& args) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004304 ALOGD_IF(debugInboundEventDetails(),
4305 "notifyKey - id=%" PRIx32 ", eventTime=%" PRId64
4306 ", deviceId=%d, source=%s, displayId=%" PRId32
4307 "policyFlags=0x%x, action=%s, flags=0x%x, keyCode=%s, scanCode=0x%x, metaState=0x%x, "
4308 "downTime=%" PRId64,
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004309 args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4310 args.displayId, args.policyFlags, KeyEvent::actionToString(args.action), args.flags,
4311 KeyEvent::getLabel(args.keyCode), args.scanCode, args.metaState, args.downTime);
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004312 Result<void> keyCheck = validateKeyEvent(args.action);
4313 if (!keyCheck.ok()) {
4314 LOG(ERROR) << "invalid key event: " << keyCheck.error();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004315 return;
4316 }
4317
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004318 uint32_t policyFlags = args.policyFlags;
4319 int32_t flags = args.flags;
4320 int32_t metaState = args.metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07004321 // InputDispatcher tracks and generates key repeats on behalf of
4322 // whatever notifies it, so repeatCount should always be set to 0
4323 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004324 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
4325 policyFlags |= POLICY_FLAG_VIRTUAL;
4326 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
4327 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004328 if (policyFlags & POLICY_FLAG_FUNCTION) {
4329 metaState |= AMETA_FUNCTION_ON;
4330 }
4331
4332 policyFlags |= POLICY_FLAG_TRUSTED;
4333
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004334 int32_t keyCode = args.keyCode;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004335 KeyEvent event;
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004336 event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC, args.action,
4337 flags, keyCode, args.scanCode, metaState, repeatCount, args.downTime,
4338 args.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004339
Michael Wright2b3c3302018-03-02 17:19:13 +00004340 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004341 mPolicy.interceptKeyBeforeQueueing(event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004342 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4343 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004344 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004345 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004346
Antonio Kantekf16f2832021-09-28 04:39:20 +00004347 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004348 { // acquire lock
4349 mLock.lock();
4350
4351 if (shouldSendKeyToInputFilterLocked(args)) {
4352 mLock.unlock();
4353
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004354 policyFlags |= POLICY_FLAG_FILTERED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004355 if (!mPolicy.filterInputEvent(event, policyFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004356 return; // event was consumed by the filter
4357 }
4358
4359 mLock.lock();
4360 }
4361
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004362 std::unique_ptr<KeyEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004363 std::make_unique<KeyEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4364 args.deviceId, args.source, args.displayId, policyFlags,
4365 args.action, flags, keyCode, args.scanCode, metaState,
4366 repeatCount, args.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004367
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004368 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004369 mLock.unlock();
4370 } // release lock
4371
4372 if (needWake) {
4373 mLooper->wake();
4374 }
4375}
4376
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004377bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs& args) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004378 return mInputFilterEnabled;
4379}
4380
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004381void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004382 if (debugInboundEventDetails()) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004383 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=%s, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004384 "displayId=%" PRId32 ", policyFlags=0x%x, "
Siarhei Vishniakou6ebd0692022-10-20 15:05:45 -07004385 "action=%s, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004386 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
4387 "yCursorPosition=%f, downTime=%" PRId64,
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004388 args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4389 args.displayId, args.policyFlags, MotionEvent::actionToString(args.action).c_str(),
4390 args.actionButton, args.flags, args.metaState, args.buttonState, args.edgeFlags,
4391 args.xPrecision, args.yPrecision, args.xCursorPosition, args.yCursorPosition,
4392 args.downTime);
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004393 for (uint32_t i = 0; i < args.getPointerCount(); i++) {
Prabir Pradhan96282b02023-02-24 22:36:17 +00004394 ALOGD(" Pointer %d: id=%d, toolType=%s, x=%f, y=%f, pressure=%f, size=%f, "
4395 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, orientation=%f",
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004396 i, args.pointerProperties[i].id,
4397 ftl::enum_string(args.pointerProperties[i].toolType).c_str(),
4398 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
4399 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
4400 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
4401 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
4402 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
4403 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
4404 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
4405 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
4406 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004407 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004408 }
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004409
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004410 Result<void> motionCheck =
4411 validateMotionEvent(args.action, args.actionButton, args.getPointerCount(),
4412 args.pointerProperties.data());
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004413 if (!motionCheck.ok()) {
4414 LOG(FATAL) << "Invalid event: " << args.dump() << "; reason: " << motionCheck.error();
4415 return;
4416 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004417
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07004418 if (DEBUG_VERIFY_EVENTS) {
4419 auto [it, _] =
4420 mVerifiersByDisplay.try_emplace(args.displayId,
4421 StringPrintf("display %" PRId32, args.displayId));
4422 Result<void> result =
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -07004423 it->second.processMovement(args.deviceId, args.source, args.action,
4424 args.getPointerCount(), args.pointerProperties.data(),
4425 args.pointerCoords.data(), args.flags);
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07004426 if (!result.ok()) {
4427 LOG(FATAL) << "Bad stream: " << result.error() << " caused by " << args.dump();
4428 }
4429 }
4430
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004431 uint32_t policyFlags = args.policyFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004432 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004433
4434 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004435 mPolicy.interceptMotionBeforeQueueing(args.displayId, args.eventTime, policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004436 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4437 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004438 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004439 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004440
Antonio Kantekf16f2832021-09-28 04:39:20 +00004441 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004442 { // acquire lock
4443 mLock.lock();
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004444 if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
4445 // Set the flag anyway if we already have an ongoing gesture. That would allow us to
4446 // complete the processing of the current stroke.
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004447 const auto touchStateIt = mTouchStatesByDisplay.find(args.displayId);
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004448 if (touchStateIt != mTouchStatesByDisplay.end()) {
4449 const TouchState& touchState = touchStateIt->second;
Linnan Li907ae732023-09-05 17:14:21 +08004450 if (touchState.hasTouchingPointers(args.deviceId) ||
4451 touchState.hasHoveringPointers(args.deviceId)) {
Siarhei Vishniakou5bf25d92023-02-08 15:43:38 -08004452 policyFlags |= POLICY_FLAG_PASS_TO_USER;
4453 }
4454 }
4455 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004456
4457 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004458 ui::Transform displayTransform;
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004459 if (const auto it = mDisplayInfos.find(args.displayId); it != mDisplayInfos.end()) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004460 displayTransform = it->second.transform;
4461 }
4462
Michael Wrightd02c5b62014-02-10 15:10:22 -08004463 mLock.unlock();
4464
4465 MotionEvent event;
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004466 event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC,
4467 args.action, args.actionButton, args.flags, args.edgeFlags,
4468 args.metaState, args.buttonState, args.classification,
4469 displayTransform, args.xPrecision, args.yPrecision,
4470 args.xCursorPosition, args.yCursorPosition, displayTransform,
Siarhei Vishniakou3218fc02023-06-15 20:41:02 -07004471 args.downTime, args.eventTime, args.getPointerCount(),
4472 args.pointerProperties.data(), args.pointerCoords.data());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004473
4474 policyFlags |= POLICY_FLAG_FILTERED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004475 if (!mPolicy.filterInputEvent(event, policyFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004476 return; // event was consumed by the filter
4477 }
4478
4479 mLock.lock();
4480 }
4481
4482 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004483 std::unique_ptr<MotionEntry> newEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004484 std::make_unique<MotionEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4485 args.deviceId, args.source, args.displayId,
4486 policyFlags, args.action, args.actionButton,
4487 args.flags, args.metaState, args.buttonState,
4488 args.classification, args.edgeFlags, args.xPrecision,
4489 args.yPrecision, args.xCursorPosition,
4490 args.yCursorPosition, args.downTime,
4491 args.pointerProperties, args.pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004492
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004493 if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4494 IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004495 !mInputFilterEnabled) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004496 const bool isDown = args.action == AMOTION_EVENT_ACTION_DOWN;
Asmita Poddardd9a6cd2023-09-26 15:35:12 +00004497 std::set<InputDeviceUsageSource> sources = getUsageSourcesForMotionArgs(args);
4498 mLatencyTracker.trackListener(args.id, isDown, args.eventTime, args.readTime,
4499 args.deviceId, sources);
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004500 }
4501
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004502 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004503 mLock.unlock();
4504 } // release lock
4505
4506 if (needWake) {
4507 mLooper->wake();
4508 }
4509}
4510
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004511void InputDispatcher::notifySensor(const NotifySensorArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004512 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004513 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4514 " sensorType=%s",
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004515 args.id, args.eventTime, args.deviceId, args.source,
4516 ftl::enum_string(args.sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004517 }
Chris Yef59a2f42020-10-16 12:55:26 -07004518
Antonio Kantekf16f2832021-09-28 04:39:20 +00004519 bool needWake = false;
Chris Yef59a2f42020-10-16 12:55:26 -07004520 { // acquire lock
4521 mLock.lock();
4522
4523 // Just enqueue a new sensor event.
4524 std::unique_ptr<SensorEntry> newEntry =
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004525 std::make_unique<SensorEntry>(args.id, args.eventTime, args.deviceId, args.source,
4526 /* policyFlags=*/0, args.hwTimestamp, args.sensorType,
4527 args.accuracy, args.accuracyChanged, args.values);
Chris Yef59a2f42020-10-16 12:55:26 -07004528
4529 needWake = enqueueInboundEventLocked(std::move(newEntry));
4530 mLock.unlock();
4531 } // release lock
4532
4533 if (needWake) {
4534 mLooper->wake();
4535 }
4536}
4537
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004538void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004539 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004540 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args.eventTime,
4541 args.deviceId, args.isOn);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004542 }
Prabir Pradhana41d2442023-04-20 21:30:40 +00004543 mPolicy.notifyVibratorState(args.deviceId, args.isOn);
Chris Yefb552902021-02-03 17:18:37 -08004544}
4545
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004546bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs& args) {
Jackal Guof9696682018-10-05 12:23:23 +08004547 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004548}
4549
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004550void InputDispatcher::notifySwitch(const NotifySwitchArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004551 if (debugInboundEventDetails()) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004552 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4553 "switchMask=0x%08x",
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004554 args.eventTime, args.policyFlags, args.switchValues, args.switchMask);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004555 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004556
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004557 uint32_t policyFlags = args.policyFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004558 policyFlags |= POLICY_FLAG_TRUSTED;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004559 mPolicy.notifySwitch(args.eventTime, args.switchValues, args.switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004560}
4561
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004562void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004563 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004564 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args.eventTime,
4565 args.deviceId);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004566 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004567
Antonio Kantekf16f2832021-09-28 04:39:20 +00004568 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004569 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004570 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004571
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004572 std::unique_ptr<DeviceResetEntry> newEntry =
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004573 std::make_unique<DeviceResetEntry>(args.id, args.eventTime, args.deviceId);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004574 needWake = enqueueInboundEventLocked(std::move(newEntry));
Siarhei Vishniakou1160ecd2023-06-28 15:57:47 -07004575
4576 for (auto& [_, verifier] : mVerifiersByDisplay) {
4577 verifier.resetDevice(args.deviceId);
4578 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004579 } // release lock
4580
4581 if (needWake) {
4582 mLooper->wake();
4583 }
4584}
4585
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004586void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) {
Prabir Pradhan65613802023-02-22 23:36:58 +00004587 if (debugInboundEventDetails()) {
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004588 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args.eventTime,
4589 args.request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004590 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004591
Antonio Kantekf16f2832021-09-28 04:39:20 +00004592 bool needWake = false;
Prabir Pradhan99987712020-11-10 18:43:05 -08004593 { // acquire lock
4594 std::scoped_lock _l(mLock);
Prabir Pradhanc392d8f2023-04-13 19:32:51 +00004595 auto entry =
4596 std::make_unique<PointerCaptureChangedEntry>(args.id, args.eventTime, args.request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004597 needWake = enqueueInboundEventLocked(std::move(entry));
4598 } // release lock
4599
4600 if (needWake) {
4601 mLooper->wake();
4602 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004603}
4604
Prabir Pradhan5735a322022-04-11 17:23:34 +00004605InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* event,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00004606 std::optional<gui::Uid> targetUid,
Prabir Pradhan5735a322022-04-11 17:23:34 +00004607 InputEventInjectionSync syncMode,
4608 std::chrono::milliseconds timeout,
4609 uint32_t policyFlags) {
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004610 Result<void> eventValidation = validateInputEvent(*event);
4611 if (!eventValidation.ok()) {
4612 LOG(INFO) << "Injection failed: invalid event: " << eventValidation.error();
4613 return InputEventInjectionResult::FAILED;
4614 }
4615
Prabir Pradhan65613802023-02-22 23:36:58 +00004616 if (debugInboundEventDetails()) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004617 LOG(INFO) << __func__ << ": targetUid=" << toString(targetUid, &uidString)
4618 << ", syncMode=" << ftl::enum_string(syncMode) << ", timeout=" << timeout.count()
4619 << "ms, policyFlags=0x" << std::hex << policyFlags << std::dec
4620 << ", event=" << *event;
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004621 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004622 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004623
Prabir Pradhan5735a322022-04-11 17:23:34 +00004624 policyFlags |= POLICY_FLAG_INJECTED | POLICY_FLAG_TRUSTED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004625
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004626 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004627 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4628 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4629 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4630 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4631 // from events that originate from actual hardware.
Siarhei Vishniakouf4043212023-09-18 19:33:03 -07004632 DeviceId resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004633 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004634 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004635 }
4636
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004637 const bool isAsync = syncMode == InputEventInjectionSync::NONE;
4638 auto injectionState = std::make_shared<InjectionState>(targetUid, isAsync);
4639
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004640 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004641 switch (event->getType()) {
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004642 case InputEventType::KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004643 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004644 const int32_t action = incomingKey.getAction();
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004645 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004646 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4647 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4648 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004649 int32_t keyCode = incomingKey.getKeyCode();
4650 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004651 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004652 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004653 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4654 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4655 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004656
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004657 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4658 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004659 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004660
4661 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4662 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004663 mPolicy.interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004664 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4665 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4666 std::to_string(t.duration().count()).c_str());
4667 }
4668 }
4669
4670 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004671 std::unique_ptr<KeyEntry> injectedEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004672 std::make_unique<KeyEntry>(incomingKey.getId(), injectionState,
4673 incomingKey.getEventTime(), resolvedDeviceId,
4674 incomingKey.getSource(), incomingKey.getDisplayId(),
4675 policyFlags, action, flags, keyCode,
4676 incomingKey.getScanCode(), metaState,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004677 incomingKey.getRepeatCount(),
4678 incomingKey.getDownTime());
4679 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004680 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004681 }
4682
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004683 case InputEventType::MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004684 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004685 const bool isPointerEvent =
4686 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4687 // If a pointer event has no displayId specified, inject it to the default display.
4688 const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
4689 ? ADISPLAY_ID_DEFAULT
4690 : event->getDisplayId();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004691 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004692
4693 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004694 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004695 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00004696 mPolicy.interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004697 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4698 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4699 std::to_string(t.duration().count()).c_str());
4700 }
4701 }
4702
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004703 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4704 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4705 }
4706
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004707 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004708 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004709 const size_t pointerCount = motionEvent.getPointerCount();
4710 const std::vector<PointerProperties>
4711 pointerProperties(motionEvent.getPointerProperties(),
4712 motionEvent.getPointerProperties() + pointerCount);
4713
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004714 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004715 std::unique_ptr<MotionEntry> injectedEntry =
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004716 std::make_unique<MotionEntry>(motionEvent.getId(), injectionState,
4717 *sampleEventTimes, resolvedDeviceId,
4718 motionEvent.getSource(), displayId, policyFlags,
4719 motionEvent.getAction(),
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004720 motionEvent.getActionButton(), flags,
4721 motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004722 motionEvent.getButtonState(),
4723 motionEvent.getClassification(),
4724 motionEvent.getEdgeFlags(),
4725 motionEvent.getXPrecision(),
4726 motionEvent.getYPrecision(),
4727 motionEvent.getRawXCursorPosition(),
4728 motionEvent.getRawYCursorPosition(),
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004729 motionEvent.getDownTime(), pointerProperties,
4730 std::vector<PointerCoords>(samplePointerCoords,
4731 samplePointerCoords +
4732 pointerCount));
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004733 transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004734 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004735 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004736 sampleEventTimes += 1;
Siarhei Vishniakou23740b92023-04-21 11:30:20 -07004737 samplePointerCoords += motionEvent.getPointerCount();
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004738 std::unique_ptr<MotionEntry> nextInjectedEntry = std::make_unique<
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004739 MotionEntry>(motionEvent.getId(), injectionState, *sampleEventTimes,
4740 resolvedDeviceId, motionEvent.getSource(), displayId,
4741 policyFlags, motionEvent.getAction(),
4742 motionEvent.getActionButton(), flags,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004743 motionEvent.getMetaState(), motionEvent.getButtonState(),
4744 motionEvent.getClassification(), motionEvent.getEdgeFlags(),
4745 motionEvent.getXPrecision(), motionEvent.getYPrecision(),
4746 motionEvent.getRawXCursorPosition(),
4747 motionEvent.getRawYCursorPosition(), motionEvent.getDownTime(),
4748 pointerProperties,
4749 std::vector<PointerCoords>(samplePointerCoords,
4750 samplePointerCoords +
4751 pointerCount));
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004752 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
4753 motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004754 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004755 }
4756 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004757 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004758
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004759 default:
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004760 LOG(WARNING) << "Cannot inject " << ftl::enum_string(event->getType()) << " events";
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004761 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004762 }
4763
Michael Wrightd02c5b62014-02-10 15:10:22 -08004764 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004765 while (!injectedEntries.empty()) {
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08004766 if (DEBUG_INJECTION) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004767 LOG(INFO) << "Injecting " << injectedEntries.front()->getDescription();
Siarhei Vishniakoud010b012023-01-18 15:00:53 -08004768 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004769 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004770 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004771 }
4772
4773 mLock.unlock();
4774
4775 if (needWake) {
4776 mLooper->wake();
4777 }
4778
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004779 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004780 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004781 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004782
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004783 if (syncMode == InputEventInjectionSync::NONE) {
4784 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004785 } else {
4786 for (;;) {
4787 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004788 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004789 break;
4790 }
4791
4792 nsecs_t remainingTimeout = endTime - now();
4793 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004794 if (DEBUG_INJECTION) {
4795 ALOGD("injectInputEvent - Timed out waiting for injection result "
4796 "to become available.");
4797 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004798 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004799 break;
4800 }
4801
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004802 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004803 }
4804
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004805 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4806 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004807 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004808 if (DEBUG_INJECTION) {
4809 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4810 injectionState->pendingForegroundDispatches);
4811 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004812 nsecs_t remainingTimeout = endTime - now();
4813 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004814 if (DEBUG_INJECTION) {
4815 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4816 "dispatches to finish.");
4817 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004818 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004819 break;
4820 }
4821
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004822 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004823 }
4824 }
4825 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004826 } // release lock
4827
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004828 if (DEBUG_INJECTION) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07004829 LOG(INFO) << "injectInputEvent - Finished with result "
4830 << ftl::enum_string(injectionResult);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004831 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004832
4833 return injectionResult;
4834}
4835
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004836std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004837 std::array<uint8_t, 32> calculatedHmac;
4838 std::unique_ptr<VerifiedInputEvent> result;
4839 switch (event.getType()) {
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004840 case InputEventType::KEY: {
Gang Wange9087892020-01-07 12:17:14 -05004841 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4842 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4843 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004844 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004845 break;
4846 }
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07004847 case InputEventType::MOTION: {
Gang Wange9087892020-01-07 12:17:14 -05004848 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4849 VerifiedMotionEvent verifiedMotionEvent =
4850 verifiedMotionEventFromMotionEvent(motionEvent);
4851 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004852 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004853 break;
4854 }
4855 default: {
4856 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4857 return nullptr;
4858 }
4859 }
4860 if (calculatedHmac == INVALID_HMAC) {
4861 return nullptr;
4862 }
tyiu1573a672023-02-21 22:38:32 +00004863 if (0 != CRYPTO_memcmp(calculatedHmac.data(), event.getHmac().data(), calculatedHmac.size())) {
Gang Wange9087892020-01-07 12:17:14 -05004864 return nullptr;
4865 }
4866 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004867}
4868
Prabir Pradhan24047542023-11-02 17:14:59 +00004869void InputDispatcher::setInjectionResult(const EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004870 InputEventInjectionResult injectionResult) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004871 if (!entry.injectionState) {
4872 // Not an injected event.
4873 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004874 }
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004875
4876 InjectionState& injectionState = *entry.injectionState;
4877 if (DEBUG_INJECTION) {
4878 LOG(INFO) << "Setting input event injection result to "
4879 << ftl::enum_string(injectionResult);
4880 }
4881
4882 if (injectionState.injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
4883 // Log the outcome since the injector did not wait for the injection result.
4884 switch (injectionResult) {
4885 case InputEventInjectionResult::SUCCEEDED:
4886 ALOGV("Asynchronous input event injection succeeded.");
4887 break;
4888 case InputEventInjectionResult::TARGET_MISMATCH:
4889 ALOGV("Asynchronous input event injection target mismatch.");
4890 break;
4891 case InputEventInjectionResult::FAILED:
4892 ALOGW("Asynchronous input event injection failed.");
4893 break;
4894 case InputEventInjectionResult::TIMED_OUT:
4895 ALOGW("Asynchronous input event injection timed out.");
4896 break;
4897 case InputEventInjectionResult::PENDING:
4898 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4899 break;
4900 }
4901 }
4902
4903 injectionState.injectionResult = injectionResult;
4904 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004905}
4906
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004907void InputDispatcher::transformMotionEntryForInjectionLocked(
4908 MotionEntry& entry, const ui::Transform& injectedTransform) const {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004909 // Input injection works in the logical display coordinate space, but the input pipeline works
4910 // display space, so we need to transform the injected events accordingly.
4911 const auto it = mDisplayInfos.find(entry.displayId);
4912 if (it == mDisplayInfos.end()) return;
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004913 const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004914
Prabir Pradhand9a2ebe2022-07-20 19:25:13 +00004915 if (entry.xCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
4916 entry.yCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
4917 const vec2 cursor =
4918 MotionEvent::calculateTransformedXY(entry.source, transformToDisplay,
4919 {entry.xCursorPosition, entry.yCursorPosition});
4920 entry.xCursorPosition = cursor.x;
4921 entry.yCursorPosition = cursor.y;
4922 }
Siarhei Vishniakouedd61202023-10-18 11:22:40 -07004923 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
Prabir Pradhan8e6ce222022-02-24 09:08:54 -08004924 entry.pointerCoords[i] =
4925 MotionEvent::calculateTransformedCoords(entry.source, transformToDisplay,
4926 entry.pointerCoords[i]);
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004927 }
4928}
4929
Prabir Pradhan24047542023-11-02 17:14:59 +00004930void InputDispatcher::incrementPendingForegroundDispatches(const EventEntry& entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004931 if (entry.injectionState) {
4932 entry.injectionState->pendingForegroundDispatches += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004933 }
4934}
4935
Prabir Pradhan24047542023-11-02 17:14:59 +00004936void InputDispatcher::decrementPendingForegroundDispatches(const EventEntry& entry) {
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004937 if (entry.injectionState) {
4938 entry.injectionState->pendingForegroundDispatches -= 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004939
Prabir Pradhana8cdbe12023-11-01 21:30:02 +00004940 if (entry.injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004941 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004942 }
4943 }
4944}
4945
chaviw98318de2021-05-19 16:45:23 -05004946const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004947 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004948 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004949 auto it = mWindowHandlesByDisplay.find(displayId);
4950 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004951}
4952
chaviw98318de2021-05-19 16:45:23 -05004953sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
Prabir Pradhan16463382023-10-12 23:03:19 +00004954 const sp<IBinder>& windowHandleToken, std::optional<int32_t> displayId) const {
arthurhungbe737672020-06-24 12:29:21 +08004955 if (windowHandleToken == nullptr) {
4956 return nullptr;
4957 }
4958
Prabir Pradhan16463382023-10-12 23:03:19 +00004959 if (!displayId) {
4960 // Look through all displays.
4961 for (auto& it : mWindowHandlesByDisplay) {
4962 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4963 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
4964 if (windowHandle->getToken() == windowHandleToken) {
4965 return windowHandle;
4966 }
Arthur Hungb92218b2018-08-14 12:00:21 +08004967 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004968 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07004969 return nullptr;
4970 }
4971
Prabir Pradhan16463382023-10-12 23:03:19 +00004972 // Only look through the requested display.
4973 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(*displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004974 if (windowHandle->getToken() == windowHandleToken) {
4975 return windowHandle;
4976 }
4977 }
4978 return nullptr;
4979}
4980
chaviw98318de2021-05-19 16:45:23 -05004981sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4982 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004983 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004984 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4985 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004986 if (handle->getId() == windowHandle->getId() &&
4987 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004988 if (windowHandle->getInfo()->displayId != it.first) {
4989 ALOGE("Found window %s in display %" PRId32
4990 ", but it should belong to display %" PRId32,
4991 windowHandle->getName().c_str(), it.first,
4992 windowHandle->getInfo()->displayId);
4993 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004994 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004995 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004996 }
4997 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004998 return nullptr;
4999}
5000
chaviw98318de2021-05-19 16:45:23 -05005001sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005002 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
5003 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005004}
5005
Prabir Pradhan33e3baa2022-12-06 20:30:22 +00005006ui::Transform InputDispatcher::getTransformLocked(int32_t displayId) const {
5007 auto displayInfoIt = mDisplayInfos.find(displayId);
5008 return displayInfoIt != mDisplayInfos.end() ? displayInfoIt->second.transform
5009 : kIdentityTransform;
5010}
5011
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005012bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& window,
5013 const MotionEntry& motionEntry) const {
5014 const WindowInfo& info = *window->getInfo();
5015
5016 // Skip spy window targets that are not valid for targeted injection.
5017 if (const auto err = verifyTargetedInjection(window, motionEntry); err) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005018 return false;
5019 }
5020
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005021 if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
5022 ALOGI("Not sending touch event to %s because it is paused", window->getName().c_str());
5023 return false;
5024 }
5025
5026 if (info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL)) {
5027 ALOGW("Not sending touch gesture to %s because it has config NO_INPUT_CHANNEL",
5028 window->getName().c_str());
5029 return false;
5030 }
5031
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005032 std::shared_ptr<Connection> connection = getConnectionLocked(window->getToken());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005033 if (connection == nullptr) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005034 ALOGW("Not sending touch to %s because there's no corresponding connection",
5035 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005036 return false;
5037 }
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005038
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005039 if (!connection->responsive) {
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005040 ALOGW("Not sending touch to %s because it is not responsive", window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005041 return false;
5042 }
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005043
5044 // Drop events that can't be trusted due to occlusion
5045 const auto [x, y] = resolveTouchedPosition(motionEntry);
5046 TouchOcclusionInfo occlusionInfo = computeTouchOcclusionInfoLocked(window, x, y);
5047 if (!isTouchTrustedLocked(occlusionInfo)) {
5048 if (DEBUG_TOUCH_OCCLUSION) {
Prabir Pradhan82e081e2022-12-06 09:50:09 +00005049 ALOGD("Stack of obscuring windows during untrusted touch (%.1f, %.1f):", x, y);
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005050 for (const auto& log : occlusionInfo.debugInfo) {
5051 ALOGD("%s", log.c_str());
5052 }
5053 }
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00005054 ALOGW("Dropping untrusted touch event due to %s/%s", occlusionInfo.obscuringPackage.c_str(),
5055 occlusionInfo.obscuringUid.toString().c_str());
Siarhei Vishniakoud4e3f3a2022-09-27 14:31:05 -07005056 return false;
5057 }
5058
5059 // Drop touch events if requested by input feature
5060 if (shouldDropInput(motionEntry, window)) {
5061 return false;
5062 }
5063
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005064 return true;
5065}
5066
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005067std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
5068 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005069 auto connectionIt = mConnectionsByToken.find(token);
5070 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07005071 return nullptr;
5072 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005073 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07005074}
5075
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005076void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05005077 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
5078 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005079 // Remove all handles on a display if there are no windows left.
5080 mWindowHandlesByDisplay.erase(displayId);
5081 return;
5082 }
5083
5084 // Since we compare the pointer of input window handles across window updates, we need
5085 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05005086 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
5087 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
5088 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07005089 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005090 }
5091
chaviw98318de2021-05-19 16:45:23 -05005092 std::vector<sp<WindowInfoHandle>> newHandles;
5093 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05005094 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005095 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005096 const bool noInputChannel =
Prabir Pradhan51e7db02022-02-07 06:02:57 -08005097 info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005098 const bool canReceiveInput =
5099 !info->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) ||
5100 !info->inputConfig.test(WindowInfo::InputConfig::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005101 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07005102 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005103 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07005104 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005105 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005106 }
5107
5108 if (info->displayId != displayId) {
5109 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
5110 handle->getName().c_str(), displayId, info->displayId);
5111 continue;
5112 }
5113
Robert Carredd13602020-04-13 17:24:34 -07005114 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
5115 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05005116 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005117 oldHandle->updateFrom(handle);
5118 newHandles.push_back(oldHandle);
5119 } else {
5120 newHandles.push_back(handle);
5121 }
5122 }
5123
5124 // Insert or replace
5125 mWindowHandlesByDisplay[displayId] = newHandles;
5126}
5127
Arthur Hungb92218b2018-08-14 12:00:21 +08005128/**
5129 * Called from InputManagerService, update window handle list by displayId that can receive input.
5130 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
5131 * If set an empty list, remove all handles from the specific display.
5132 * For focused handle, check if need to change and send a cancel event to previous one.
5133 * For removed handle, check if need to send a cancel event if already in touch.
5134 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00005135void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05005136 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005137 if (DEBUG_FOCUS) {
5138 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05005139 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005140 windowList += iwh->getName() + " ";
5141 }
5142 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
5143 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005144
Prabir Pradhand65552b2021-10-07 11:23:50 -07005145 // Check preconditions for new input windows
chaviw98318de2021-05-19 16:45:23 -05005146 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07005147 const WindowInfo& info = *window->getInfo();
5148
5149 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
Prabir Pradhan51e7db02022-02-07 06:02:57 -08005150 const bool noInputWindow = info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005151 if (noInputWindow && window->getToken() != nullptr) {
5152 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
5153 window->getName().c_str());
5154 window->releaseChannel();
5155 }
Prabir Pradhand65552b2021-10-07 11:23:50 -07005156
Prabir Pradhan5c85e052021-12-22 02:27:12 -08005157 // Ensure all spy windows are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005158 LOG_ALWAYS_FATAL_IF(info.isSpy() &&
5159 !info.inputConfig.test(
5160 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhan5c85e052021-12-22 02:27:12 -08005161 "%s has feature SPY, but is not a trusted overlay.",
5162 window->getName().c_str());
5163
Prabir Pradhand65552b2021-10-07 11:23:50 -07005164 // Ensure all stylus interceptors are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005165 LOG_ALWAYS_FATAL_IF(info.interceptsStylus() &&
5166 !info.inputConfig.test(
5167 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhand65552b2021-10-07 11:23:50 -07005168 "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
5169 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05005170 }
5171
Arthur Hung72d8dc32020-03-28 00:48:39 +00005172 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05005173 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005174
chaviw98318de2021-05-19 16:45:23 -05005175 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07005176
chaviw98318de2021-05-19 16:45:23 -05005177 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00005178
Vishnu Nairc519ff72021-01-21 08:23:08 -08005179 std::optional<FocusResolver::FocusChanges> changes =
5180 mFocusResolver.setInputWindows(displayId, windowHandles);
5181 if (changes) {
5182 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00005183 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005184
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005185 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5186 mTouchStatesByDisplay.find(displayId);
5187 if (stateIt != mTouchStatesByDisplay.end()) {
5188 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00005189 for (size_t i = 0; i < state.windows.size();) {
5190 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005191 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07005192 LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName()
5193 << " in display %" << displayId;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005194 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00005195 getInputChannelLocked(touchedWindow.windowHandle->getToken());
5196 if (touchedInputChannel != nullptr) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00005197 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Arthur Hung72d8dc32020-03-28 00:48:39 +00005198 "touched window was removed");
5199 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005200 // Since we are about to drop the touch, cancel the events for the wallpaper as
5201 // well.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005202 if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005203 touchedWindow.windowHandle->getInfo()->inputConfig.test(
5204 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005205 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
Arthur Hungc539dbb2022-12-08 07:45:36 +00005206 synthesizeCancelationEventsForWindowLocked(wallpaper, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00005207 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005208 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005209 state.windows.erase(state.windows.begin() + i);
5210 } else {
5211 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005212 }
5213 }
arthurhungb89ccb02020-12-30 16:19:01 +08005214
arthurhung6d4bed92021-03-17 11:59:33 +08005215 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08005216 // could just clear the state here.
Arthur Hung3915c1f2022-05-31 07:17:17 +00005217 if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId &&
arthurhung6d4bed92021-03-17 11:59:33 +08005218 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08005219 windowHandles.end()) {
Arthur Hung3915c1f2022-05-31 07:17:17 +00005220 ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str());
5221 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08005222 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08005223 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005224 }
Arthur Hung25e2af12020-03-26 12:58:37 +00005225
Arthur Hung72d8dc32020-03-28 00:48:39 +00005226 // Release information for windows that are no longer present.
5227 // This ensures that unused input channels are released promptly.
5228 // Otherwise, they might stick around until the window handle is destroyed
5229 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05005230 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07005231 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00005232 if (DEBUG_FOCUS) {
5233 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00005234 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00005235 oldWindowHandle->releaseChannel();
Arthur Hung25e2af12020-03-26 12:58:37 +00005236 }
chaviw291d88a2019-02-14 10:33:58 -08005237 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005238}
5239
5240void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07005241 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005242 if (DEBUG_FOCUS) {
5243 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
5244 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
5245 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005246 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005247 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07005248 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005249 } // release lock
5250
5251 // Wake up poll loop since it may need to make new input dispatching choices.
5252 mLooper->wake();
5253}
5254
Vishnu Nair599f1412021-06-21 10:39:58 -07005255void InputDispatcher::setFocusedApplicationLocked(
5256 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
5257 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
5258 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
5259
5260 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
5261 return; // This application is already focused. No need to wake up or change anything.
5262 }
5263
5264 // Set the new application handle.
5265 if (inputApplicationHandle != nullptr) {
5266 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
5267 } else {
5268 mFocusedApplicationHandlesByDisplay.erase(displayId);
5269 }
5270
5271 // No matter what the old focused application was, stop waiting on it because it is
5272 // no longer focused.
5273 resetNoFocusedWindowTimeoutLocked();
5274}
5275
Tiger Huang721e26f2018-07-24 22:26:19 +08005276/**
5277 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
5278 * the display not specified.
5279 *
5280 * We track any unreleased events for each window. If a window loses the ability to receive the
5281 * released event, we will send a cancel event to it. So when the focused display is changed, we
5282 * cancel all the unreleased display-unspecified events for the focused window on the old focused
5283 * display. The display-specified events won't be affected.
5284 */
5285void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005286 if (DEBUG_FOCUS) {
5287 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
5288 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005289 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005290 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08005291
5292 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005293 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08005294 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005295 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005296 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07005297 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08005298 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005299 CancelationOptions
Michael Wrightfb04fd52022-11-24 22:31:11 +00005300 options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005301 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005302 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08005303 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
5304 }
5305 }
5306 mFocusedDisplayId = displayId;
5307
Chris Ye3c2d6f52020-08-09 10:39:48 -07005308 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08005309 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00005310 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08005311
Vishnu Nairad321cd2020-08-20 16:40:21 -07005312 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08005313 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08005314 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005315 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08005316 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08005317 }
5318 }
5319 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005320 } // release lock
5321
5322 // Wake up poll loop since it may need to make new input dispatching choices.
5323 mLooper->wake();
5324}
5325
Michael Wrightd02c5b62014-02-10 15:10:22 -08005326void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005327 if (DEBUG_FOCUS) {
5328 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
5329 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005330
5331 bool changed;
5332 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005333 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005334
5335 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
5336 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005337 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005338 }
5339
5340 if (mDispatchEnabled && !enabled) {
5341 resetAndDropEverythingLocked("dispatcher is being disabled");
5342 }
5343
5344 mDispatchEnabled = enabled;
5345 mDispatchFrozen = frozen;
5346 changed = true;
5347 } else {
5348 changed = false;
5349 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005350 } // release lock
5351
5352 if (changed) {
5353 // Wake up poll loop since it may need to make new input dispatching choices.
5354 mLooper->wake();
5355 }
5356}
5357
5358void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005359 if (DEBUG_FOCUS) {
5360 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
5361 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005362
5363 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005364 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005365
5366 if (mInputFilterEnabled == enabled) {
5367 return;
5368 }
5369
5370 mInputFilterEnabled = enabled;
5371 resetAndDropEverythingLocked("input filter is being enabled or disabled");
5372 } // release lock
5373
5374 // Wake up poll loop since there might be work to do to drop everything.
5375 mLooper->wake();
5376}
5377
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005378bool InputDispatcher::setInTouchMode(bool inTouchMode, gui::Pid pid, gui::Uid uid,
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00005379 bool hasPermission, int32_t displayId) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00005380 bool needWake = false;
5381 {
5382 std::scoped_lock lock(mLock);
Antonio Kantek15beb512022-06-13 22:35:41 +00005383 ALOGD_IF(DEBUG_TOUCH_MODE,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005384 "Request to change touch mode to %s (calling pid=%s, uid=%s, "
Antonio Kantek15beb512022-06-13 22:35:41 +00005385 "hasPermission=%s, target displayId=%d, mTouchModePerDisplay[displayId]=%s)",
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005386 toString(inTouchMode), pid.toString().c_str(), uid.toString().c_str(),
5387 toString(hasPermission), displayId,
Antonio Kantek15beb512022-06-13 22:35:41 +00005388 mTouchModePerDisplay.count(displayId) == 0
5389 ? "not set"
5390 : std::to_string(mTouchModePerDisplay[displayId]).c_str());
5391
Antonio Kantek15beb512022-06-13 22:35:41 +00005392 auto touchModeIt = mTouchModePerDisplay.find(displayId);
5393 if (touchModeIt != mTouchModePerDisplay.end() && touchModeIt->second == inTouchMode) {
Antonio Kantekea47acb2021-12-23 12:41:25 -08005394 return false;
Antonio Kantekf16f2832021-09-28 04:39:20 +00005395 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005396 if (!hasPermission) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005397 if (!focusedWindowIsOwnedByLocked(pid, uid) &&
5398 !recentWindowsAreOwnedByLocked(pid, uid)) {
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005399 ALOGD("Touch mode switch rejected, caller (pid=%s, uid=%s) doesn't own the focused "
Antonio Kantek48710e42022-03-24 14:19:30 -07005400 "window nor none of the previously interacted window",
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005401 pid.toString().c_str(), uid.toString().c_str());
Antonio Kantekea47acb2021-12-23 12:41:25 -08005402 return false;
5403 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00005404 }
Antonio Kantek15beb512022-06-13 22:35:41 +00005405 mTouchModePerDisplay[displayId] = inTouchMode;
5406 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode,
5407 displayId);
Antonio Kantekf16f2832021-09-28 04:39:20 +00005408 needWake = enqueueInboundEventLocked(std::move(entry));
5409 } // release lock
5410
5411 if (needWake) {
5412 mLooper->wake();
5413 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005414 return true;
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08005415}
5416
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005417bool InputDispatcher::focusedWindowIsOwnedByLocked(gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005418 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
5419 if (focusedToken == nullptr) {
5420 return false;
5421 }
5422 sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken);
5423 return isWindowOwnedBy(windowHandle, pid, uid);
5424}
5425
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005426bool InputDispatcher::recentWindowsAreOwnedByLocked(gui::Pid pid, gui::Uid uid) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005427 return std::find_if(mInteractionConnectionTokens.begin(), mInteractionConnectionTokens.end(),
5428 [&](const sp<IBinder>& connectionToken) REQUIRES(mLock) {
5429 const sp<WindowInfoHandle> windowHandle =
5430 getWindowHandleLocked(connectionToken);
5431 return isWindowOwnedBy(windowHandle, pid, uid);
5432 }) != mInteractionConnectionTokens.end();
5433}
5434
Bernardo Rufinoea97d182020-08-19 14:43:14 +01005435void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
5436 if (opacity < 0 || opacity > 1) {
5437 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
5438 return;
5439 }
5440
5441 std::scoped_lock lock(mLock);
5442 mMaximumObscuringOpacityForTouch = opacity;
5443}
5444
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005445std::tuple<TouchState*, TouchedWindow*, int32_t /*displayId*/>
5446InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) {
Arthur Hungabbb9d82021-09-01 14:52:30 +00005447 for (auto& [displayId, state] : mTouchStatesByDisplay) {
5448 for (TouchedWindow& w : state.windows) {
5449 if (w.windowHandle->getToken() == token) {
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005450 return std::make_tuple(&state, &w, displayId);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005451 }
5452 }
5453 }
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005454 return std::make_tuple(nullptr, nullptr, ADISPLAY_ID_DEFAULT);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005455}
5456
arthurhungb89ccb02020-12-30 16:19:01 +08005457bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5458 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08005459 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005460 if (DEBUG_FOCUS) {
5461 ALOGD("Trivial transfer to same window.");
5462 }
chaviwfbe5d9c2018-12-26 12:23:37 -08005463 return true;
5464 }
5465
Michael Wrightd02c5b62014-02-10 15:10:22 -08005466 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005467 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005468
Arthur Hungabbb9d82021-09-01 14:52:30 +00005469 // Find the target touch state and touched window by fromToken.
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005470 auto [state, touchedWindow, displayId] = findTouchStateWindowAndDisplayLocked(fromToken);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005471
Arthur Hungabbb9d82021-09-01 14:52:30 +00005472 if (state == nullptr || touchedWindow == nullptr) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005473 ALOGD("Touch transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005474 return false;
5475 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005476 std::set<int32_t> deviceIds = touchedWindow->getTouchingDeviceIds();
5477 if (deviceIds.size() != 1) {
Siarhei Vishniakou827d1ac2023-07-21 16:37:51 -07005478 LOG(INFO) << "Can't transfer touch. Currently touching devices: " << dumpSet(deviceIds)
5479 << " for window: " << touchedWindow->dump();
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005480 return false;
5481 }
5482 const int32_t deviceId = *deviceIds.begin();
Arthur Hungabbb9d82021-09-01 14:52:30 +00005483
Arthur Hungabbb9d82021-09-01 14:52:30 +00005484 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
5485 if (toWindowHandle == nullptr) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005486 ALOGW("Cannot transfer touch because to window not found.");
Arthur Hungabbb9d82021-09-01 14:52:30 +00005487 return false;
5488 }
5489
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005490 if (DEBUG_FOCUS) {
5491 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00005492 touchedWindow->windowHandle->getName().c_str(),
5493 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005494 }
5495
Arthur Hungabbb9d82021-09-01 14:52:30 +00005496 // Erase old window.
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005497 ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags;
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005498 std::bitset<MAX_POINTER_ID + 1> pointerIds = touchedWindow->getTouchingPointers(deviceId);
Arthur Hungc539dbb2022-12-08 07:45:36 +00005499 sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
Arthur Hungabbb9d82021-09-01 14:52:30 +00005500 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005501
Arthur Hungabbb9d82021-09-01 14:52:30 +00005502 // Add new window.
Vaibhav Devmurari882bd9b2022-06-23 14:54:54 +00005503 nsecs_t downTimeInTarget = now();
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005504 ftl::Flags<InputTarget::Flags> newTargetFlags =
5505 oldTargetFlags & (InputTarget::Flags::SPLIT | InputTarget::Flags::DISPATCH_AS_IS);
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005506 if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005507 newTargetFlags |= InputTarget::Flags::FOREGROUND;
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005508 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005509 state->addOrUpdateWindow(toWindowHandle, newTargetFlags, deviceId, pointerIds,
5510 downTimeInTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005511
Arthur Hungabbb9d82021-09-01 14:52:30 +00005512 // Store the dragging window.
5513 if (isDragDrop) {
Arthur Hungb75c2aa2022-07-15 09:35:36 +00005514 if (pointerIds.count() != 1) {
5515 ALOGW("The drag and drop cannot be started when there is no pointer or more than 1"
5516 " pointer on the window.");
Arthur Hung54745652022-04-20 07:17:41 +00005517 return false;
5518 }
Arthur Hungb75c2aa2022-07-15 09:35:36 +00005519 // Track the pointer id for drag window and generate the drag state.
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08005520 const size_t id = firstMarkedBit(pointerIds);
Arthur Hung54745652022-04-20 07:17:41 +00005521 mDragState = std::make_unique<DragState>(toWindowHandle, id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005522 }
5523
Arthur Hungabbb9d82021-09-01 14:52:30 +00005524 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005525 std::shared_ptr<Connection> fromConnection = getConnectionLocked(fromToken);
5526 std::shared_ptr<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005527 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005528 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005529 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5530 "transferring touch from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005531 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Arthur Hungc539dbb2022-12-08 07:45:36 +00005532 synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection,
5533 newTargetFlags);
5534
5535 // Check if the wallpaper window should deliver the corresponding event.
5536 transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07005537 *state, deviceId, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005538 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005539 } // release lock
5540
5541 // Wake up poll loop since it may need to make new input dispatching choices.
5542 mLooper->wake();
5543 return true;
5544}
5545
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005546/**
5547 * Get the touched foreground window on the given display.
5548 * Return null if there are no windows touched on that display, or if more than one foreground
5549 * window is being touched.
5550 */
5551sp<WindowInfoHandle> InputDispatcher::findTouchedForegroundWindowLocked(int32_t displayId) const {
5552 auto stateIt = mTouchStatesByDisplay.find(displayId);
5553 if (stateIt == mTouchStatesByDisplay.end()) {
5554 ALOGI("No touch state on display %" PRId32, displayId);
5555 return nullptr;
5556 }
5557
5558 const TouchState& state = stateIt->second;
5559 sp<WindowInfoHandle> touchedForegroundWindow;
5560 // If multiple foreground windows are touched, return nullptr
5561 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakou253f4642022-11-09 13:42:06 -08005562 if (window.targetFlags.test(InputTarget::Flags::FOREGROUND)) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005563 if (touchedForegroundWindow != nullptr) {
5564 ALOGI("Two or more foreground windows: %s and %s",
5565 touchedForegroundWindow->getName().c_str(),
5566 window.windowHandle->getName().c_str());
5567 return nullptr;
5568 }
5569 touchedForegroundWindow = window.windowHandle;
5570 }
5571 }
5572 return touchedForegroundWindow;
5573}
5574
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005575// Binder call
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005576bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken, int32_t displayId) {
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005577 sp<IBinder> fromToken;
5578 { // acquire lock
5579 std::scoped_lock _l(mLock);
Arthur Hungabbb9d82021-09-01 14:52:30 +00005580 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005581 if (toWindowHandle == nullptr) {
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005582 ALOGW("Could not find window associated with token=%p on display %" PRId32,
5583 destChannelToken.get(), displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005584 return false;
5585 }
5586
Siarhei Vishniakou7ae7afd2022-03-31 15:26:13 -07005587 sp<WindowInfoHandle> from = findTouchedForegroundWindowLocked(displayId);
5588 if (from == nullptr) {
5589 ALOGE("Could not find a source window in %s for %p", __func__, destChannelToken.get());
5590 return false;
5591 }
5592
5593 fromToken = from->getToken();
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005594 } // release lock
5595
5596 return transferTouchFocus(fromToken, destChannelToken);
5597}
5598
Michael Wrightd02c5b62014-02-10 15:10:22 -08005599void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005600 if (DEBUG_FOCUS) {
5601 ALOGD("Resetting and dropping all events (%s).", reason);
5602 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005603
Michael Wrightfb04fd52022-11-24 22:31:11 +00005604 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005605 synthesizeCancelationEventsForAllConnectionsLocked(options);
5606
5607 resetKeyRepeatLocked();
5608 releasePendingEventLocked();
5609 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005610 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005611
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005612 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005613 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005614}
5615
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005616void InputDispatcher::logDispatchStateLocked() const {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005617 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005618 dumpDispatchStateLocked(dump);
5619
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005620 std::istringstream stream(dump);
5621 std::string line;
5622
5623 while (std::getline(stream, line, '\n')) {
Siarhei Vishniakoua235c042023-05-02 09:59:09 -07005624 ALOGI("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005625 }
5626}
5627
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005628std::string InputDispatcher::dumpPointerCaptureStateLocked() const {
Prabir Pradhan99987712020-11-10 18:43:05 -08005629 std::string dump;
5630
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005631 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5632 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005633
5634 std::string windowName = "None";
5635 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005636 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005637 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5638 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5639 : "token has capture without window";
5640 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005641 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005642
5643 return dump;
5644}
5645
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005646void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005647 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5648 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5649 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005650 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005651
Tiger Huang721e26f2018-07-24 22:26:19 +08005652 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5653 dump += StringPrintf(INDENT "FocusedApplications:\n");
5654 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5655 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005656 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005657 const std::chrono::duration timeout =
5658 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005659 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005660 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005661 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005662 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005663 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005664 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005665 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005666
Vishnu Nairc519ff72021-01-21 08:23:08 -08005667 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005668 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005669
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005670 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005671 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07005672 for (const auto& [displayId, state] : mTouchStatesByDisplay) {
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -08005673 std::string touchStateDump = addLinePrefix(state.dump(), INDENT2);
5674 dump += INDENT2 + std::to_string(displayId) + " : " + touchStateDump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005675 }
5676 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005677 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005678 }
5679
arthurhung6d4bed92021-03-17 11:59:33 +08005680 if (mDragState) {
5681 dump += StringPrintf(INDENT "DragState:\n");
5682 mDragState->dump(dump, INDENT2);
5683 }
5684
Arthur Hungb92218b2018-08-14 12:00:21 +08005685 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005686 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5687 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5688 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5689 const auto& displayInfo = it->second;
5690 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5691 displayInfo.logicalHeight);
5692 displayInfo.transform.dump(dump, "transform", INDENT4);
5693 } else {
5694 dump += INDENT2 "No DisplayInfo found!\n";
5695 }
5696
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005697 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005698 dump += INDENT2 "Windows:\n";
5699 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005700 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5701 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005702
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005703 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005704 "inputConfig=%s, alpha=%.2f, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005705 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005706 "applicationInfo.name=%s, "
5707 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005708 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005709 i, windowInfo->name.c_str(), windowInfo->id,
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005710 windowInfo->displayId,
5711 windowInfo->inputConfig.string().c_str(),
Chavi Weingarten7f019192023-08-08 20:39:01 +00005712 windowInfo->alpha, windowInfo->frame.left,
5713 windowInfo->frame.top, windowInfo->frame.right,
5714 windowInfo->frame.bottom, windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005715 windowInfo->applicationInfo.name.c_str(),
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07005716 binderToString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005717 dump += dumpRegion(windowInfo->touchableRegion);
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005718 dump += StringPrintf(", ownerPid=%s, ownerUid=%s, dispatchingTimeout=%" PRId64
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005719 "ms, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005720 "touchOcclusionMode=%s\n",
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005721 windowInfo->ownerPid.toString().c_str(),
Prabir Pradhan8a5c41d2023-06-08 19:13:46 +00005722 windowInfo->ownerUid.toString().c_str(),
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005723 millis(windowInfo->dispatchingTimeout),
Siarhei Vishniakou63b63612023-04-12 11:00:23 -07005724 binderToString(windowInfo->token).c_str(),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005725 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005726 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005727 }
5728 } else {
5729 dump += INDENT2 "Windows: <none>\n";
5730 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005731 }
5732 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005733 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005734 }
5735
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005736 if (!mGlobalMonitorsByDisplay.empty()) {
5737 for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
5738 dump += StringPrintf(INDENT "Global monitors on display %d:\n", displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00005739 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005740 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005741 } else {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005742 dump += INDENT "Global Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005743 }
5744
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005745 const nsecs_t currentTime = now();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005746
5747 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005748 if (!mRecentQueue.empty()) {
5749 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Prabir Pradhan24047542023-11-02 17:14:59 +00005750 for (const std::shared_ptr<const EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005751 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005752 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005753 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005754 }
5755 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005756 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005757 }
5758
5759 // Dump event currently being dispatched.
5760 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005761 dump += INDENT "PendingEvent:\n";
5762 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005763 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005764 dump += StringPrintf(", age=%" PRId64 "ms\n",
5765 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005766 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005767 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005768 }
5769
5770 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005771 if (!mInboundQueue.empty()) {
5772 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Prabir Pradhan24047542023-11-02 17:14:59 +00005773 for (const std::shared_ptr<const EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005774 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005775 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005776 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005777 }
5778 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005779 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005780 }
5781
Prabir Pradhancef936d2021-07-21 16:17:52 +00005782 if (!mCommandQueue.empty()) {
5783 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5784 } else {
5785 dump += INDENT "CommandQueue: <empty>\n";
5786 }
5787
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005788 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005789 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005790 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005791 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005792 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005793 connection->inputChannel->getFd().get(),
5794 connection->getInputChannelName().c_str(),
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005795 connection->getWindowName().c_str(),
5796 ftl::enum_string(connection->status).c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005797 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005798
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005799 if (!connection->outboundQueue.empty()) {
5800 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5801 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005802 dump += dumpQueue(connection->outboundQueue, currentTime);
5803
Michael Wrightd02c5b62014-02-10 15:10:22 -08005804 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005805 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005806 }
5807
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005808 if (!connection->waitQueue.empty()) {
5809 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5810 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005811 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005812 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005813 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005814 }
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -07005815 std::stringstream inputStateDump;
5816 inputStateDump << connection->inputState;
5817 if (!isEmpty(inputStateDump)) {
5818 dump += INDENT3 "InputState: ";
5819 dump += inputStateDump.str() + "\n";
5820 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005821 }
5822 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005823 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005824 }
5825
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07005826 dump += "input_flags::remove_app_switch_drops() = ";
Siarhei Vishniakou17f12282023-11-02 13:40:29 -07005827 dump += toString(REMOVE_APP_SWITCH_DROPS);
Siarhei Vishniakou6520a582023-10-27 21:53:45 -07005828 dump += "\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005829 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005830 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5831 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005832 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005833 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005834 }
5835
Antonio Kantek15beb512022-06-13 22:35:41 +00005836 if (!mTouchModePerDisplay.empty()) {
5837 dump += INDENT "TouchModePerDisplay:\n";
5838 for (const auto& [displayId, touchMode] : mTouchModePerDisplay) {
5839 dump += StringPrintf(INDENT2 "Display: %" PRId32 " TouchMode: %s\n", displayId,
5840 std::to_string(touchMode).c_str());
5841 }
5842 } else {
5843 dump += INDENT "TouchModePerDisplay: <none>\n";
5844 }
5845
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005846 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005847 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5848 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5849 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005850 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005851 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005852}
5853
Siarhei Vishniakou4c9d6ff2023-04-18 11:23:20 -07005854void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00005855 const size_t numMonitors = monitors.size();
5856 for (size_t i = 0; i < numMonitors; i++) {
5857 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005858 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005859 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5860 dump += "\n";
5861 }
5862}
5863
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005864class LooperEventCallback : public LooperCallback {
5865public:
5866 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5867 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5868
5869private:
5870 std::function<int(int events)> mCallback;
5871};
5872
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005873Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005874 if (DEBUG_CHANNEL_CREATION) {
5875 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5876 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005877
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005878 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005879 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005880 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005881
5882 if (result) {
5883 return base::Error(result) << "Failed to open input channel pair with name " << name;
5884 }
5885
Michael Wrightd02c5b62014-02-10 15:10:22 -08005886 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005887 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005888 const sp<IBinder>& token = serverChannel->getConnectionToken();
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005889 auto&& fd = serverChannel->getFd();
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005890 std::shared_ptr<Connection> connection =
5891 std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/false,
5892 mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005893
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005894 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5895 ALOGE("Created a new connection, but the token %p is already known", token.get());
5896 }
5897 mConnectionsByToken.emplace(token, connection);
5898
5899 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5900 this, std::placeholders::_1, token);
5901
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005902 mLooper->addFd(fd.get(), 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005903 nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005904 } // release lock
5905
5906 // Wake the looper because some connections have changed.
5907 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005908 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005909}
5910
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005911Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005912 const std::string& name,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00005913 gui::Pid pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005914 std::shared_ptr<InputChannel> serverChannel;
5915 std::unique_ptr<InputChannel> clientChannel;
5916 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5917 if (result) {
5918 return base::Error(result) << "Failed to open input channel pair with name " << name;
5919 }
5920
Michael Wright3dd60e22019-03-27 22:06:44 +00005921 { // acquire lock
5922 std::scoped_lock _l(mLock);
5923
5924 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005925 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5926 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005927 }
5928
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005929 std::shared_ptr<Connection> connection =
5930 std::make_shared<Connection>(serverChannel, /*monitor=*/true, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005931 const sp<IBinder>& token = serverChannel->getConnectionToken();
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005932 auto&& fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005933
5934 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5935 ALOGE("Created a new connection, but the token %p is already known", token.get());
5936 }
5937 mConnectionsByToken.emplace(token, connection);
5938 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5939 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005940
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005941 mGlobalMonitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005942
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005943 mLooper->addFd(fd.get(), 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07005944 nullptr);
Michael Wright3dd60e22019-03-27 22:06:44 +00005945 }
Garfield Tan15601662020-09-22 15:32:38 -07005946
Michael Wright3dd60e22019-03-27 22:06:44 +00005947 // Wake the looper because some connections have changed.
5948 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005949 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005950}
5951
Garfield Tan15601662020-09-22 15:32:38 -07005952status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005953 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005954 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005955
Harry Cutts33476232023-01-30 19:57:29 +00005956 status_t status = removeInputChannelLocked(connectionToken, /*notify=*/false);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005957 if (status) {
5958 return status;
5959 }
5960 } // release lock
5961
5962 // Wake the poll loop because removing the connection may have changed the current
5963 // synchronization state.
5964 mLooper->wake();
5965 return OK;
5966}
5967
Garfield Tan15601662020-09-22 15:32:38 -07005968status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5969 bool notify) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07005970 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005971 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005972 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005973 return BAD_VALUE;
5974 }
5975
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005976 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005977
Michael Wrightd02c5b62014-02-10 15:10:22 -08005978 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005979 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005980 }
5981
Tomasz Wasilczyk32024602023-11-16 10:17:54 -08005982 mLooper->removeFd(connection->inputChannel->getFd().get());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005983
5984 nsecs_t currentTime = now();
5985 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5986
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005987 connection->status = Connection::Status::ZOMBIE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005988 return OK;
5989}
5990
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005991void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005992 for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
5993 auto& [displayId, monitors] = *it;
5994 std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
5995 return monitor.inputChannel->getConnectionToken() == connectionToken;
5996 });
Michael Wright3dd60e22019-03-27 22:06:44 +00005997
Michael Wright3dd60e22019-03-27 22:06:44 +00005998 if (monitors.empty()) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005999 it = mGlobalMonitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08006000 } else {
6001 ++it;
6002 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006003 }
6004}
6005
Michael Wright3dd60e22019-03-27 22:06:44 +00006006status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006007 std::scoped_lock _l(mLock);
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00006008 return pilferPointersLocked(token);
6009}
Michael Wright3dd60e22019-03-27 22:06:44 +00006010
Vaibhav Devmurari6abcf8f2022-06-06 10:08:05 +00006011status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006012 const std::shared_ptr<InputChannel> requestingChannel = getInputChannelLocked(token);
6013 if (!requestingChannel) {
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006014 LOG(WARNING)
6015 << "Attempted to pilfer pointers from an un-registered channel or invalid token";
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006016 return BAD_VALUE;
Michael Wright3dd60e22019-03-27 22:06:44 +00006017 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006018
Siarhei Vishniakou40b8fbd2022-11-04 10:50:26 -07006019 auto [statePtr, windowPtr, displayId] = findTouchStateWindowAndDisplayLocked(token);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006020 if (statePtr == nullptr || windowPtr == nullptr) {
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006021 LOG(WARNING)
6022 << "Attempted to pilfer points from a channel without any on-going pointer streams."
6023 " Ignoring.";
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006024 return BAD_VALUE;
6025 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006026 std::set<int32_t> deviceIds = windowPtr->getTouchingDeviceIds();
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07006027 if (deviceIds.empty()) {
6028 LOG(WARNING) << "Can't pilfer: no touching devices in window: " << windowPtr->dump();
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006029 return BAD_VALUE;
6030 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006031
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006032 for (const DeviceId deviceId : deviceIds) {
6033 TouchState& state = *statePtr;
6034 TouchedWindow& window = *windowPtr;
6035 // Send cancel events to all the input channels we're stealing from.
6036 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6037 "input channel stole pointer stream");
6038 options.deviceId = deviceId;
6039 options.displayId = displayId;
6040 std::bitset<MAX_POINTER_ID + 1> pointerIds = window.getTouchingPointers(deviceId);
6041 options.pointerIds = pointerIds;
6042 std::string canceledWindows;
6043 for (const TouchedWindow& w : state.windows) {
6044 const std::shared_ptr<InputChannel> channel =
6045 getInputChannelLocked(w.windowHandle->getToken());
6046 if (channel != nullptr && channel->getConnectionToken() != token) {
6047 synthesizeCancelationEventsForInputChannelLocked(channel, options);
6048 canceledWindows += canceledWindows.empty() ? "[" : ", ";
6049 canceledWindows += channel->getName();
6050 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006051 }
Siarhei Vishniakou8384e0d2023-09-18 18:48:27 -07006052 canceledWindows += canceledWindows.empty() ? "[]" : "]";
6053 LOG(INFO) << "Channel " << requestingChannel->getName()
6054 << " is stealing input gesture for device " << deviceId << " from "
6055 << canceledWindows;
6056
6057 // Prevent the gesture from being sent to any other windows.
6058 // This only blocks relevant pointers to be sent to other windows
6059 window.addPilferingPointers(deviceId, pointerIds);
6060
6061 state.cancelPointersForWindowsExcept(deviceId, pointerIds, token);
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006062 }
Michael Wright3dd60e22019-03-27 22:06:44 +00006063 return OK;
6064}
6065
Prabir Pradhan99987712020-11-10 18:43:05 -08006066void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
6067 { // acquire lock
6068 std::scoped_lock _l(mLock);
6069 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05006070 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08006071 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
6072 windowHandle != nullptr ? windowHandle->getName().c_str()
6073 : "token without window");
6074 }
6075
Vishnu Nairc519ff72021-01-21 08:23:08 -08006076 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08006077 if (focusedToken != windowToken) {
6078 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
6079 enabled ? "enable" : "disable");
6080 return;
6081 }
6082
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006083 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006084 ALOGW("Ignoring request to %s Pointer Capture: "
6085 "window has %s requested pointer capture.",
6086 enabled ? "enable" : "disable", enabled ? "already" : "not");
6087 return;
6088 }
6089
Christine Franksb768bb42021-11-29 12:11:31 -08006090 if (enabled) {
6091 if (std::find(mIneligibleDisplaysForPointerCapture.begin(),
6092 mIneligibleDisplaysForPointerCapture.end(),
6093 mFocusedDisplayId) != mIneligibleDisplaysForPointerCapture.end()) {
6094 ALOGW("Ignoring request to enable Pointer Capture: display is not eligible");
6095 return;
6096 }
6097 }
6098
Prabir Pradhan99987712020-11-10 18:43:05 -08006099 setPointerCaptureLocked(enabled);
6100 } // release lock
6101
6102 // Wake the thread to process command entries.
6103 mLooper->wake();
6104}
6105
Christine Franksb768bb42021-11-29 12:11:31 -08006106void InputDispatcher::setDisplayEligibilityForPointerCapture(int32_t displayId, bool isEligible) {
6107 { // acquire lock
6108 std::scoped_lock _l(mLock);
6109 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
6110 if (!isEligible) {
6111 mIneligibleDisplaysForPointerCapture.push_back(displayId);
6112 }
6113 } // release lock
6114}
6115
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006116std::optional<gui::Pid> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006117 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00006118 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006119 if (monitor.inputChannel->getConnectionToken() == token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08006120 return monitor.pid;
Michael Wright3dd60e22019-03-27 22:06:44 +00006121 }
6122 }
6123 }
6124 return std::nullopt;
6125}
6126
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006127std::shared_ptr<Connection> InputDispatcher::getConnectionLocked(
6128 const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07006129 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006130 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08006131 }
6132
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00006133 for (const auto& [token, connection] : mConnectionsByToken) {
6134 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006135 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006136 }
6137 }
Robert Carr4e670e52018-08-15 13:26:12 -07006138
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07006139 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006140}
6141
Siarhei Vishniakouad991402020-10-28 11:40:09 -05006142std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006143 std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakouad991402020-10-28 11:40:09 -05006144 if (connection == nullptr) {
6145 return "<nullptr>";
6146 }
6147 return connection->getInputChannelName();
6148}
6149
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006150void InputDispatcher::removeConnectionLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006151 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00006152 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07006153}
6154
Prabir Pradhancef936d2021-07-21 16:17:52 +00006155void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006156 const std::shared_ptr<Connection>& connection,
6157 uint32_t seq, bool handled,
6158 nsecs_t consumeTime) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006159 // Handle post-event policy actions.
Prabir Pradhan24047542023-11-02 17:14:59 +00006160 std::unique_ptr<const KeyEntry> fallbackKeyEntry;
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006161
6162 { // Start critical section
6163 auto dispatchEntryIt =
6164 std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6165 [seq](auto& e) { return e->seq == seq; });
6166 if (dispatchEntryIt == connection->waitQueue.end()) {
6167 return;
6168 }
6169
6170 DispatchEntry& dispatchEntry = **dispatchEntryIt;
6171
6172 const nsecs_t eventDuration = finishTime - dispatchEntry.deliveryTime;
6173 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
6174 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
6175 ns2ms(eventDuration), dispatchEntry.eventEntry->getDescription().c_str());
6176 }
6177 if (shouldReportFinishedEvent(dispatchEntry, *connection)) {
6178 mLatencyTracker.trackFinishedEvent(dispatchEntry.eventEntry->id,
6179 connection->inputChannel->getConnectionToken(),
6180 dispatchEntry.deliveryTime, consumeTime, finishTime);
6181 }
6182
6183 if (dispatchEntry.eventEntry->type == EventEntry::Type::KEY) {
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006184 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*(dispatchEntry.eventEntry));
6185 fallbackKeyEntry =
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006186 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006187 }
6188 } // End critical section: The -LockedInterruptable methods may have released the lock.
Prabir Pradhancef936d2021-07-21 16:17:52 +00006189
6190 // Dequeue the event and start the next cycle.
6191 // Because the lock might have been released, it is possible that the
6192 // contents of the wait queue to have been drained, so we need to double-check
6193 // a few things.
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006194 auto entryIt = std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6195 [seq](auto& e) { return e->seq == seq; });
6196 if (entryIt != connection->waitQueue.end()) {
6197 std::unique_ptr<DispatchEntry> dispatchEntry = std::move(*entryIt);
6198 connection->waitQueue.erase(entryIt);
6199
Prabir Pradhancef936d2021-07-21 16:17:52 +00006200 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
6201 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
6202 if (!connection->responsive) {
6203 connection->responsive = isConnectionResponsive(*connection);
6204 if (connection->responsive) {
6205 // The connection was unresponsive, and now it's responsive.
6206 processConnectionResponsiveLocked(*connection);
6207 }
6208 }
6209 traceWaitQueueLength(*connection);
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006210 if (fallbackKeyEntry && connection->status == Connection::Status::NORMAL) {
6211 const InputTarget target{.inputChannel = connection->inputChannel,
6212 .flags = dispatchEntry->targetFlags};
6213 enqueueDispatchEntryLocked(connection, std::move(fallbackKeyEntry), target,
6214 InputTarget::Flags::DISPATCH_AS_IS);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006215 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006216 releaseDispatchEntry(std::move(dispatchEntry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00006217 }
6218
6219 // Start the next dispatch cycle for this connection.
6220 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006221}
6222
Prabir Pradhancef936d2021-07-21 16:17:52 +00006223void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
6224 const sp<IBinder>& newToken) {
6225 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
6226 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006227 mPolicy.notifyFocusChanged(oldToken, newToken);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006228 };
6229 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006230}
6231
Prabir Pradhancef936d2021-07-21 16:17:52 +00006232void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
6233 auto command = [this, token, x, y]() REQUIRES(mLock) {
6234 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006235 mPolicy.notifyDropWindow(token, x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006236 };
6237 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08006238}
6239
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006240void InputDispatcher::onAnrLocked(const std::shared_ptr<Connection>& connection) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006241 if (connection == nullptr) {
6242 LOG_ALWAYS_FATAL("Caller must check for nullness");
6243 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006244 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
6245 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006246 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006247 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006248 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006249 return;
6250 }
6251 /**
6252 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
6253 * may not be the one that caused the timeout to occur. One possibility is that window timeout
6254 * has changed. This could cause newer entries to time out before the already dispatched
6255 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
6256 * processes the events linearly. So providing information about the oldest entry seems to be
6257 * most useful.
6258 */
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006259 DispatchEntry& oldestEntry = *connection->waitQueue.front();
6260 const nsecs_t currentWait = now() - oldestEntry.deliveryTime;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006261 std::string reason =
6262 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006263 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006264 ns2ms(currentWait),
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006265 oldestEntry.eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006266 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06006267 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006268
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006269 processConnectionUnresponsiveLocked(*connection, std::move(reason));
6270
6271 // Stop waking up for events on this connection, it is already unresponsive
6272 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006273}
6274
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05006275void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
6276 std::string reason =
6277 StringPrintf("%s does not have a focused window", application->getName().c_str());
6278 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006279
Yabin Cui8eb9c552023-06-08 18:05:07 +00006280 auto command = [this, app = std::move(application)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006281 scoped_unlock unlock(mLock);
Yabin Cuiced952f2023-06-09 21:12:51 +00006282 mPolicy.notifyNoFocusedWindowAnr(app);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006283 };
6284 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00006285}
6286
chaviw98318de2021-05-19 16:45:23 -05006287void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006288 const std::string& reason) {
6289 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
6290 updateLastAnrStateLocked(windowLabel, reason);
6291}
6292
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05006293void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
6294 const std::string& reason) {
6295 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006296 updateLastAnrStateLocked(windowLabel, reason);
6297}
6298
6299void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
6300 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006301 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07006302 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006303 struct tm tm;
6304 localtime_r(&t, &tm);
6305 char timestr[64];
6306 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006307 mLastAnrState.clear();
6308 mLastAnrState += INDENT "ANR:\n";
6309 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07006310 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
6311 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006312 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006313}
6314
Prabir Pradhancef936d2021-07-21 16:17:52 +00006315void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
Prabir Pradhan24047542023-11-02 17:14:59 +00006316 const KeyEntry& entry) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006317 const KeyEvent event = createKeyEvent(entry);
6318 nsecs_t delay = 0;
6319 { // release lock
6320 scoped_unlock unlock(mLock);
6321 android::base::Timer t;
Prabir Pradhana41d2442023-04-20 21:30:40 +00006322 delay = mPolicy.interceptKeyBeforeDispatching(focusedWindowToken, event, entry.policyFlags);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006323 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
6324 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
6325 std::to_string(t.duration().count()).c_str());
6326 }
6327 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08006328
6329 if (delay < 0) {
Michael Wright5caf55a2022-11-24 22:31:42 +00006330 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00006331 } else if (delay == 0) {
Michael Wright5caf55a2022-11-24 22:31:42 +00006332 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006333 } else {
Michael Wright5caf55a2022-11-24 22:31:42 +00006334 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006335 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006336 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006337}
6338
Prabir Pradhancef936d2021-07-21 16:17:52 +00006339void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006340 std::optional<gui::Pid> pid,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006341 std::string reason) {
Yabin Cui8eb9c552023-06-08 18:05:07 +00006342 auto command = [this, token, pid, r = std::move(reason)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006343 scoped_unlock unlock(mLock);
Yabin Cuiced952f2023-06-09 21:12:51 +00006344 mPolicy.notifyWindowUnresponsive(token, pid, r);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006345 };
6346 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006347}
6348
Prabir Pradhanedd96402022-02-15 01:46:16 -08006349void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006350 std::optional<gui::Pid> pid) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08006351 auto command = [this, token, pid]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006352 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006353 mPolicy.notifyWindowResponsive(token, pid);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006354 };
6355 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006356}
6357
6358/**
6359 * Tell the policy that a connection has become unresponsive so that it can start ANR.
6360 * Check whether the connection of interest is a monitor or a window, and add the corresponding
6361 * command entry to the command queue.
6362 */
6363void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
6364 std::string reason) {
6365 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006366 std::optional<gui::Pid> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006367 if (connection.monitor) {
6368 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
6369 reason.c_str());
Prabir Pradhanedd96402022-02-15 01:46:16 -08006370 pid = findMonitorPidByTokenLocked(connectionToken);
6371 } else {
6372 // The connection is a window
6373 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
6374 reason.c_str());
6375 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6376 if (handle != nullptr) {
6377 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006378 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006379 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08006380 sendWindowUnresponsiveCommandLocked(connectionToken, pid, std::move(reason));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006381}
6382
6383/**
6384 * Tell the policy that a connection has become responsive so that it can stop ANR.
6385 */
6386void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
6387 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanaeebeb42023-06-13 19:53:03 +00006388 std::optional<gui::Pid> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006389 if (connection.monitor) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08006390 pid = findMonitorPidByTokenLocked(connectionToken);
6391 } else {
6392 // The connection is a window
6393 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6394 if (handle != nullptr) {
6395 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006396 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006397 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08006398 sendWindowResponsiveCommandLocked(connectionToken, pid);
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00006399}
6400
Prabir Pradhan24047542023-11-02 17:14:59 +00006401std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptable(
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006402 const std::shared_ptr<Connection>& connection, DispatchEntry& dispatchEntry,
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006403 const KeyEntry& keyEntry, bool handled) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006404 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006405 if (!handled) {
6406 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006407 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006408 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006409 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006410 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006411
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006412 // Get the fallback key state.
6413 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006414 int32_t originalKeyCode = keyEntry.keyCode;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006415 std::optional<int32_t> fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006416 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006417 connection->inputState.removeFallbackKey(originalKeyCode);
6418 }
6419
Prabir Pradhan8c90d782023-09-15 21:16:44 +00006420 if (handled || !dispatchEntry.hasForegroundTarget()) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006421 // If the application handles the original key for which we previously
6422 // generated a fallback or if the window is not a foreground window,
6423 // then cancel the associated fallback key, if any.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006424 if (fallbackKeyCode) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006425 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006426 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6427 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
6428 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6429 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
6430 keyEntry.policyFlags);
6431 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006432 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006433 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006434
6435 mLock.unlock();
6436
Prabir Pradhana41d2442023-04-20 21:30:40 +00006437 if (const auto unhandledKeyFallback =
6438 mPolicy.dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
6439 event, keyEntry.policyFlags);
6440 unhandledKeyFallback) {
6441 event = *unhandledKeyFallback;
6442 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006443
6444 mLock.lock();
6445
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006446 // Cancel the fallback key.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006447 if (*fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00006448 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006449 "application handled the original non-fallback key "
6450 "or is no longer a foreground target, "
6451 "canceling previously dispatched fallback key");
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006452 options.keyCode = *fallbackKeyCode;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006453 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006454 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006455 connection->inputState.removeFallbackKey(originalKeyCode);
6456 }
6457 } else {
6458 // If the application did not handle a non-fallback key, first check
6459 // that we are in a good state to perform unhandled key event processing
6460 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006461 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006462 if (!fallbackKeyCode && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006463 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6464 ALOGD("Unhandled key event: Skipping unhandled key event processing "
6465 "since this is not an initial down. "
6466 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6467 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6468 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006469 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006470 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006471
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006472 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006473 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6474 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
6475 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6476 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6477 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006478 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006479
6480 mLock.unlock();
6481
Prabir Pradhana41d2442023-04-20 21:30:40 +00006482 bool fallback = false;
6483 if (auto fb = mPolicy.dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
6484 event, keyEntry.policyFlags);
6485 fb) {
6486 fallback = true;
6487 event = *fb;
6488 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006489
6490 mLock.lock();
6491
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08006492 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006493 connection->inputState.removeFallbackKey(originalKeyCode);
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006494 return {};
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006495 }
6496
6497 // Latch the fallback keycode for this key on an initial down.
6498 // The fallback keycode cannot change at any other point in the lifecycle.
6499 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006500 if (fallback) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006501 *fallbackKeyCode = event.getKeyCode();
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006502 } else {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006503 *fallbackKeyCode = AKEYCODE_UNKNOWN;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006504 }
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006505 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006506 }
6507
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006508 ALOG_ASSERT(fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006509
6510 // Cancel the fallback key if the policy decides not to send it anymore.
6511 // We will continue to dispatch the key to the policy but we will no
6512 // longer dispatch a fallback key to the application.
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006513 if (*fallbackKeyCode != AKEYCODE_UNKNOWN &&
6514 (!fallback || *fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006515 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6516 if (fallback) {
6517 ALOGD("Unhandled key event: Policy requested to send key %d"
6518 "as a fallback for %d, but on the DOWN it had requested "
6519 "to send %d instead. Fallback canceled.",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006520 event.getKeyCode(), originalKeyCode, *fallbackKeyCode);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006521 } else {
6522 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6523 "but on the DOWN it had requested to send %d. "
6524 "Fallback canceled.",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006525 originalKeyCode, *fallbackKeyCode);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006526 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006527 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006528
Michael Wrightfb04fd52022-11-24 22:31:11 +00006529 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006530 "canceling fallback, policy no longer desires it");
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006531 options.keyCode = *fallbackKeyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006532 synthesizeCancelationEventsForConnectionLocked(connection, options);
6533
6534 fallback = false;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006535 *fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006536 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006537 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006538 }
6539 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006540
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006541 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6542 {
6543 std::string msg;
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006544 const std::map<int32_t, int32_t>& fallbackKeys =
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006545 connection->inputState.getFallbackKeys();
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006546 for (const auto& [key, value] : fallbackKeys) {
6547 msg += StringPrintf(", %d->%d", key, value);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006548 }
6549 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6550 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006551 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006552 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006553
6554 if (fallback) {
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006555 // Return the fallback key that we want dispatched to the channel.
6556 std::unique_ptr<KeyEntry> newEntry =
6557 std::make_unique<KeyEntry>(mIdGenerator.nextId(), keyEntry.injectionState,
6558 event.getEventTime(), event.getDeviceId(),
6559 event.getSource(), event.getDisplayId(),
6560 keyEntry.policyFlags, keyEntry.action,
6561 event.getFlags() | AKEY_EVENT_FLAG_FALLBACK,
6562 *fallbackKeyCode, event.getScanCode(),
6563 event.getMetaState(), event.getRepeatCount(),
6564 event.getDownTime());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006565 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6566 ALOGD("Unhandled key event: Dispatching fallback key. "
6567 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -07006568 originalKeyCode, *fallbackKeyCode, keyEntry.metaState);
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006569 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006570 return newEntry;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006571 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006572 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6573 ALOGD("Unhandled key event: No fallback key.");
6574 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006575
6576 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006577 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006578 }
6579 }
Prabir Pradhanb9dd1642023-11-02 18:05:36 +00006580 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -08006581}
6582
Michael Wrightd02c5b62014-02-10 15:10:22 -08006583void InputDispatcher::traceInboundQueueLengthLocked() {
6584 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006585 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006586 }
6587}
6588
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006589void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006590 if (ATRACE_ENABLED()) {
6591 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006592 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6593 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006594 }
6595}
6596
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006597void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006598 if (ATRACE_ENABLED()) {
6599 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006600 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6601 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006602 }
6603}
6604
Siarhei Vishniakou5e20f272023-06-08 17:24:44 -07006605void InputDispatcher::dump(std::string& dump) const {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006606 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006607
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006608 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006609 dumpDispatchStateLocked(dump);
6610
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006611 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006612 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006613 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006614 }
6615}
6616
6617void InputDispatcher::monitor() {
6618 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006619 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006620 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006621 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006622}
6623
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006624/**
6625 * Wake up the dispatcher and wait until it processes all events and commands.
6626 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6627 * this method can be safely called from any thread, as long as you've ensured that
6628 * the work you are interested in completing has already been queued.
6629 */
Siarhei Vishniakoua66d65e2023-06-16 10:32:51 -07006630bool InputDispatcher::waitForIdle() const {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006631 /**
6632 * Timeout should represent the longest possible time that a device might spend processing
6633 * events and commands.
6634 */
6635 constexpr std::chrono::duration TIMEOUT = 100ms;
6636 std::unique_lock lock(mLock);
6637 mLooper->wake();
6638 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6639 return result == std::cv_status::no_timeout;
6640}
6641
Vishnu Naire798b472020-07-23 13:52:21 -07006642/**
6643 * Sets focus to the window identified by the token. This must be called
6644 * after updating any input window handles.
6645 *
6646 * Params:
6647 * request.token - input channel token used to identify the window that should gain focus.
6648 * request.focusedToken - the token that the caller expects currently to be focused. If the
6649 * specified token does not match the currently focused window, this request will be dropped.
6650 * If the specified focused token matches the currently focused window, the call will succeed.
6651 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6652 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6653 * when requesting the focus change. This determines which request gets
6654 * precedence if there is a focus change request from another source such as pointer down.
6655 */
Vishnu Nair958da932020-08-21 17:12:37 -07006656void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6657 { // acquire lock
6658 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006659 std::optional<FocusResolver::FocusChanges> changes =
6660 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6661 if (changes) {
6662 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006663 }
6664 } // release lock
6665 // Wake up poll loop since it may need to make new input dispatching choices.
6666 mLooper->wake();
6667}
6668
Vishnu Nairc519ff72021-01-21 08:23:08 -08006669void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6670 if (changes.oldFocus) {
6671 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006672 if (focusedInputChannel) {
Michael Wrightfb04fd52022-11-24 22:31:11 +00006673 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006674 "focus left window");
6675 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Harry Cutts33476232023-01-30 19:57:29 +00006676 enqueueFocusEventLocked(changes.oldFocus, /*hasFocus=*/false, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006677 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006678 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006679 if (changes.newFocus) {
Siarhei Vishniakouc033dfb2023-10-03 10:45:16 -07006680 resetNoFocusedWindowTimeoutLocked();
Harry Cutts33476232023-01-30 19:57:29 +00006681 enqueueFocusEventLocked(changes.newFocus, /*hasFocus=*/true, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006682 }
6683
Prabir Pradhan99987712020-11-10 18:43:05 -08006684 // If a window has pointer capture, then it must have focus. We need to ensure that this
6685 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6686 // If the window loses focus before it loses pointer capture, then the window can be in a state
6687 // where it has pointer capture but not focus, violating the contract. Therefore we must
6688 // dispatch the pointer capture event before the focus event. Since focus events are added to
6689 // the front of the queue (above), we add the pointer capture event to the front of the queue
6690 // after the focus events are added. This ensures the pointer capture event ends up at the
6691 // front.
6692 disablePointerCaptureForcedLocked();
6693
Vishnu Nairc519ff72021-01-21 08:23:08 -08006694 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006695 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006696 }
6697}
Vishnu Nair958da932020-08-21 17:12:37 -07006698
Prabir Pradhan99987712020-11-10 18:43:05 -08006699void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006700 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006701 return;
6702 }
6703
6704 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6705
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006706 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006707 setPointerCaptureLocked(false);
6708 }
6709
6710 if (!mWindowTokenWithPointerCapture) {
6711 // No need to send capture changes because no window has capture.
6712 return;
6713 }
6714
6715 if (mPendingEvent != nullptr) {
6716 // Move the pending event to the front of the queue. This will give the chance
6717 // for the pending event to be dropped if it is a captured event.
6718 mInboundQueue.push_front(mPendingEvent);
6719 mPendingEvent = nullptr;
6720 }
6721
6722 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006723 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006724 mInboundQueue.push_front(std::move(entry));
6725}
6726
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006727void InputDispatcher::setPointerCaptureLocked(bool enable) {
6728 mCurrentPointerCaptureRequest.enable = enable;
6729 mCurrentPointerCaptureRequest.seq++;
6730 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006731 scoped_unlock unlock(mLock);
Prabir Pradhana41d2442023-04-20 21:30:40 +00006732 mPolicy.setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006733 };
6734 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006735}
6736
Vishnu Nair599f1412021-06-21 10:39:58 -07006737void InputDispatcher::displayRemoved(int32_t displayId) {
6738 { // acquire lock
6739 std::scoped_lock _l(mLock);
6740 // Set an empty list to remove all handles from the specific display.
Harry Cutts101ee9b2023-07-06 18:04:14 +00006741 setInputWindowsLocked(/*windowInfoHandles=*/{}, displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006742 setFocusedApplicationLocked(displayId, nullptr);
6743 // Call focus resolver to clean up stale requests. This must be called after input windows
6744 // have been removed for the removed display.
6745 mFocusResolver.displayRemoved(displayId);
Christine Franksb768bb42021-11-29 12:11:31 -08006746 // Reset pointer capture eligibility, regardless of previous state.
6747 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
Antonio Kantek15beb512022-06-13 22:35:41 +00006748 // Remove the associated touch mode state.
6749 mTouchModePerDisplay.erase(displayId);
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -07006750 mVerifiersByDisplay.erase(displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006751 } // release lock
6752
6753 // Wake up poll loop since it may need to make new input dispatching choices.
6754 mLooper->wake();
6755}
6756
Patrick Williamsd828f302023-04-28 17:52:08 -05006757void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update) {
chaviw15fab6f2021-06-07 14:15:52 -05006758 // The listener sends the windows as a flattened array. Separate the windows by display for
6759 // more convenient parsing.
6760 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
Patrick Williamsd828f302023-04-28 17:52:08 -05006761 for (const auto& info : update.windowInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006762 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07006763 handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
chaviw15fab6f2021-06-07 14:15:52 -05006764 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006765
6766 { // acquire lock
6767 std::scoped_lock _l(mLock);
Prabir Pradhan814fe082022-07-22 20:22:18 +00006768
6769 // Ensure that we have an entry created for all existing displays so that if a displayId has
6770 // no windows, we can tell that the windows were removed from the display.
6771 for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
6772 handlesPerDisplay[displayId];
6773 }
6774
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006775 mDisplayInfos.clear();
Patrick Williamsd828f302023-04-28 17:52:08 -05006776 for (const auto& displayInfo : update.displayInfos) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006777 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6778 }
6779
6780 for (const auto& [displayId, handles] : handlesPerDisplay) {
6781 setInputWindowsLocked(handles, displayId);
6782 }
Patrick Williams9464b2c2023-05-23 11:22:04 -05006783
6784 if (update.vsyncId < mWindowInfosVsyncId) {
6785 ALOGE("Received out of order window infos update. Last update vsync id: %" PRId64
6786 ", current update vsync id: %" PRId64,
6787 mWindowInfosVsyncId, update.vsyncId);
6788 }
6789 mWindowInfosVsyncId = update.vsyncId;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006790 }
6791 // Wake up poll loop since it may need to make new input dispatching choices.
6792 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006793}
6794
Vishnu Nair062a8672021-09-03 16:07:44 -07006795bool InputDispatcher::shouldDropInput(
6796 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006797 if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
6798 (windowHandle->getInfo()->inputConfig.test(
6799 WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
Vishnu Nair062a8672021-09-03 16:07:44 -07006800 isWindowObscuredLocked(windowHandle))) {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006801 ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on "
6802 "display %" PRId32 ".",
Vishnu Nair062a8672021-09-03 16:07:44 -07006803 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006804 windowHandle->getInfo()->inputConfig.string().c_str(),
Vishnu Nair062a8672021-09-03 16:07:44 -07006805 windowHandle->getInfo()->displayId);
6806 return true;
6807 }
6808 return false;
6809}
6810
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006811void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
Patrick Williamsd828f302023-04-28 17:52:08 -05006812 const gui::WindowInfosUpdate& update) {
6813 mDispatcher.onWindowInfosChanged(update);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006814}
6815
Arthur Hungdfd528e2021-12-08 13:23:04 +00006816void InputDispatcher::cancelCurrentTouch() {
6817 {
6818 std::scoped_lock _l(mLock);
6819 ALOGD("Canceling all ongoing pointer gestures on all displays.");
Michael Wrightfb04fd52022-11-24 22:31:11 +00006820 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
Arthur Hungdfd528e2021-12-08 13:23:04 +00006821 "cancel current touch");
6822 synthesizeCancelationEventsForAllConnectionsLocked(options);
6823
6824 mTouchStatesByDisplay.clear();
Arthur Hungdfd528e2021-12-08 13:23:04 +00006825 }
6826 // Wake up poll loop since there might be work to do.
6827 mLooper->wake();
6828}
6829
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08006830void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout) {
6831 std::scoped_lock _l(mLock);
6832 mMonitorDispatchingTimeout = timeout;
6833}
6834
Arthur Hungc539dbb2022-12-08 07:45:36 +00006835void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
6836 const sp<WindowInfoHandle>& oldWindowHandle,
6837 const sp<WindowInfoHandle>& newWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006838 TouchState& state, int32_t deviceId, int32_t pointerId,
Siarhei Vishniakoubf880522023-05-01 11:03:22 -07006839 std::vector<InputTarget>& targets) const {
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08006840 std::bitset<MAX_POINTER_ID + 1> pointerIds;
6841 pointerIds.set(pointerId);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006842 const bool oldHasWallpaper = oldWindowHandle->getInfo()->inputConfig.test(
6843 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6844 const bool newHasWallpaper = targetFlags.test(InputTarget::Flags::FOREGROUND) &&
6845 newWindowHandle->getInfo()->inputConfig.test(
6846 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6847 const sp<WindowInfoHandle> oldWallpaper =
6848 oldHasWallpaper ? state.getWallpaperWindow() : nullptr;
6849 const sp<WindowInfoHandle> newWallpaper =
6850 newHasWallpaper ? findWallpaperWindowBelow(newWindowHandle) : nullptr;
6851 if (oldWallpaper == newWallpaper) {
6852 return;
6853 }
6854
6855 if (oldWallpaper != nullptr) {
Siarhei Vishniakou0026b4c2022-11-10 19:33:29 -08006856 const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper);
Siarhei Vishniakou2899c552023-07-10 18:20:46 -07006857 addPointerWindowTargetLocked(oldWallpaper,
6858 oldTouchedWindow.targetFlags |
6859 InputTarget::Flags::DISPATCH_AS_SLIPPERY_EXIT,
6860 pointerIds, oldTouchedWindow.getDownTimeInTarget(deviceId),
6861 targets);
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006862 state.removeTouchingPointerFromWindow(deviceId, pointerId, oldWallpaper);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006863 }
6864
6865 if (newWallpaper != nullptr) {
6866 state.addOrUpdateWindow(newWallpaper,
6867 InputTarget::Flags::DISPATCH_AS_SLIPPERY_ENTER |
6868 InputTarget::Flags::WINDOW_IS_OBSCURED |
6869 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006870 deviceId, pointerIds);
Arthur Hungc539dbb2022-12-08 07:45:36 +00006871 }
6872}
6873
6874void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags,
6875 ftl::Flags<InputTarget::Flags> newTargetFlags,
6876 const sp<WindowInfoHandle> fromWindowHandle,
6877 const sp<WindowInfoHandle> toWindowHandle,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006878 TouchState& state, int32_t deviceId,
Siarhei Vishniakou8a878352023-01-30 14:05:01 -08006879 std::bitset<MAX_POINTER_ID + 1> pointerIds) {
Arthur Hungc539dbb2022-12-08 07:45:36 +00006880 const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
6881 fromWindowHandle->getInfo()->inputConfig.test(
6882 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6883 const bool newHasWallpaper = newTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
6884 toWindowHandle->getInfo()->inputConfig.test(
6885 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
6886
6887 const sp<WindowInfoHandle> oldWallpaper =
6888 oldHasWallpaper ? state.getWallpaperWindow() : nullptr;
6889 const sp<WindowInfoHandle> newWallpaper =
6890 newHasWallpaper ? findWallpaperWindowBelow(toWindowHandle) : nullptr;
6891 if (oldWallpaper == newWallpaper) {
6892 return;
6893 }
6894
6895 if (oldWallpaper != nullptr) {
6896 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6897 "transferring touch focus to another window");
6898 state.removeWindowByToken(oldWallpaper->getToken());
6899 synthesizeCancelationEventsForWindowLocked(oldWallpaper, options);
6900 }
6901
6902 if (newWallpaper != nullptr) {
6903 nsecs_t downTimeInTarget = now();
6904 ftl::Flags<InputTarget::Flags> wallpaperFlags =
6905 oldTargetFlags & (InputTarget::Flags::SPLIT | InputTarget::Flags::DISPATCH_AS_IS);
6906 wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED |
6907 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
Siarhei Vishniakou0836a302023-05-03 13:54:30 -07006908 state.addOrUpdateWindow(newWallpaper, wallpaperFlags, deviceId, pointerIds,
6909 downTimeInTarget);
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006910 std::shared_ptr<Connection> wallpaperConnection =
6911 getConnectionLocked(newWallpaper->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00006912 if (wallpaperConnection != nullptr) {
Siarhei Vishniakou1069fa82023-04-19 12:14:39 -07006913 std::shared_ptr<Connection> toConnection =
6914 getConnectionLocked(toWindowHandle->getToken());
Arthur Hungc539dbb2022-12-08 07:45:36 +00006915 toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState);
6916 synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, wallpaperConnection,
6917 wallpaperFlags);
6918 }
6919 }
6920}
6921
6922sp<WindowInfoHandle> InputDispatcher::findWallpaperWindowBelow(
6923 const sp<WindowInfoHandle>& windowHandle) const {
6924 const std::vector<sp<WindowInfoHandle>>& windowHandles =
6925 getWindowHandlesLocked(windowHandle->getInfo()->displayId);
6926 bool foundWindow = false;
6927 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
6928 if (!foundWindow && otherHandle != windowHandle) {
6929 continue;
6930 }
6931 if (windowHandle == otherHandle) {
6932 foundWindow = true;
6933 continue;
6934 }
6935
6936 if (otherHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::IS_WALLPAPER)) {
6937 return otherHandle;
6938 }
6939 }
6940 return nullptr;
6941}
6942
Siarhei Vishniakoufa2a0492023-11-14 13:13:18 -08006943void InputDispatcher::setKeyRepeatConfiguration(std::chrono::nanoseconds timeout,
6944 std::chrono::nanoseconds delay) {
Nergi Rahardi730cf3c2023-04-13 12:41:17 +09006945 std::scoped_lock _l(mLock);
6946
Siarhei Vishniakoufa2a0492023-11-14 13:13:18 -08006947 mConfig.keyRepeatTimeout = timeout.count();
6948 mConfig.keyRepeatDelay = delay.count();
Nergi Rahardi730cf3c2023-04-13 12:41:17 +09006949}
6950
Prabir Pradhan64f21d22023-11-28 21:19:42 +00006951bool InputDispatcher::isPointerInWindow(const sp<android::IBinder>& token, int32_t displayId,
6952 DeviceId deviceId, int32_t pointerId) {
6953 std::scoped_lock _l(mLock);
6954 auto touchStateIt = mTouchStatesByDisplay.find(displayId);
6955 if (touchStateIt == mTouchStatesByDisplay.end()) {
6956 return false;
6957 }
6958 for (const TouchedWindow& window : touchStateIt->second.windows) {
6959 if (window.windowHandle->getToken() == token &&
6960 (window.hasTouchingPointer(deviceId, pointerId) ||
6961 window.hasHoveringPointer(deviceId, pointerId))) {
6962 return true;
6963 }
6964 }
6965 return false;
6966}
6967
Garfield Tane84e6f92019-08-29 17:28:41 -07006968} // namespace android::inputdispatcher